Skip to content

Commit

Permalink
test(DssVestSuckable): add coverage for USDS vest
Browse files Browse the repository at this point in the history
  • Loading branch information
amusingaxl committed Oct 11, 2024
1 parent 70cd780 commit 59b0a51
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 23 deletions.
7 changes: 7 additions & 0 deletions src/DssVest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,13 @@ contract DssVestSuckable is DssVest {
vat.suck(chainlog.getAddress("MCD_VOW"), address(this), mul(_amt, RAY));
join.exit(_guy, _amt);
}

/**
@dev Compatibility with older implementations of `DssVestSuckable`
*/
function daiJoin() external view returns (address) {
return address(join);
}
}

/*
Expand Down
84 changes: 61 additions & 23 deletions src/DssVest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ interface GemLike {
function approve(address, uint256) external returns (bool);
}

interface DaiLike is GemLike {
interface ERC20Like is GemLike {
function balanceOf(address) external returns (uint256);
}

Expand Down Expand Up @@ -92,15 +92,17 @@ contract DssVestTest is DSTest {

DssVestMintable mVest;
DssVestSuckable sVest;
DssVestSuckable sVestUsds;
DssVestTransferrable tVest;
Manager boss;

ChainlogLike chainlog;
DSTokenLike gem;
MkrAuthorityLike authority;
VatLike vat;
DaiLike dai;
ERC20Like dai;
JoinLike daiJoin;
ERC20Like usds;
JoinLike usdsJoin;
EndLike end;

Expand All @@ -113,16 +115,19 @@ contract DssVestTest is DSTest {
gem = DSTokenLike ( chainlog.getAddress("MCD_GOV"));
authority = MkrAuthorityLike( chainlog.getAddress("GOV_GUARD"));
vat = VatLike( chainlog.getAddress("MCD_VAT"));
dai = DaiLike( chainlog.getAddress("MCD_DAI"));
dai = ERC20Like( chainlog.getAddress("MCD_DAI"));
daiJoin = JoinLike( chainlog.getAddress("MCD_JOIN_DAI"));
usds = ERC20Like( chainlog.getAddress("USDS"));
usdsJoin = JoinLike( chainlog.getAddress("USDS_JOIN"));
end = EndLike( chainlog.getAddress("MCD_END"));
VOW = chainlog.getAddress("MCD_VOW");

mVest = new DssVestMintable(address(gem));
mVest.file("cap", (2000 * WAD) / (4 * 365 days));
sVest = new DssVestSuckable(address(chainlog), address(usdsJoin));
sVest = new DssVestSuckable(address(chainlog), address(daiJoin));
sVest.file("cap", (2000 * WAD) / (4 * 365 days));
sVestUsds = new DssVestSuckable(address(chainlog), address(usdsJoin));
sVestUsds.file("cap", (2000 * WAD) / (4 * 365 days));
boss = new Manager();
tVest = new DssVestTransferrable(address(boss), address(dai));
tVest.file("cap", (2000 * WAD) / (4 * 365 days));
Expand All @@ -145,13 +150,28 @@ contract DssVestTest is DSTest {
);
assertEq(vat.wards(address(sVest)), 1);

hevm.store(
address(vat),
keccak256(abi.encode(address(sVestUsds), uint256(0))),
bytes32(uint256(1))
);
assertEq(vat.wards(address(sVestUsds)), 1);

// Give boss 10000 DAI
hevm.store(
address(dai),
keccak256(abi.encode(address(boss), uint(2))),
bytes32(uint256(10000 * WAD))
);
assertEq(dai.balanceOf(address(boss)), 10000 * WAD);

// Give boss 10000 USDS
hevm.store(
address(usds),
keccak256(abi.encode(address(boss), uint(2))),
bytes32(uint256(10000 * WAD))
);
assertEq(usds.balanceOf(address(boss)), 10000 * WAD, "Failed to check usds balance");
}

function testCost() public {
Expand Down Expand Up @@ -290,34 +310,34 @@ contract DssVestTest is DSTest {

function testAccrued() public {
uint256 id = mVest.create(address(this), 100 * days_vest, block.timestamp + 10 days, 100 days, 0, address(0));
assertTrue(mVest.valid(id));
assertTrue(mVest.valid(id), "0");

assertEq(mVest.accrued(id), 0);
assertEq(mVest.accrued(id), 0, "1");
hevm.warp(block.timestamp + 43200);
assertEq(mVest.unpaid(id), 0); // inside cliff
assertEq(mVest.accrued(id), 0);
assertEq(mVest.unpaid(id), 0, "2"); // inside cliff
assertEq(mVest.accrued(id), 0, "3");
hevm.warp(block.timestamp + 12 hours + 11 days);
assertEq(mVest.unpaid(id), days_vest * 2); // past cliff
assertEq(mVest.accrued(id), days_vest * 2);
assertEq(mVest.unpaid(id), days_vest * 2, "3.1"); // past cliff
assertEq(mVest.accrued(id), days_vest * 2, "4");
hevm.warp(block.timestamp + 2 days);
assertEq(mVest.unpaid(id), days_vest * 4); // past cliff
assertEq(mVest.accrued(id), days_vest * 4);
assertEq(mVest.unpaid(id), days_vest * 4, "5"); // past cliff
assertEq(mVest.accrued(id), days_vest * 4, "6");
mVest.vest(id);
assertEq(mVest.unpaid(id), 0);
assertEq(mVest.accrued(id), days_vest * 4);
assertEq(gem.balanceOf(address(this)), days_vest * 4);
assertEq(mVest.unpaid(id), 0, "7");
assertEq(mVest.accrued(id), days_vest * 4, "8");
assertEq(gem.balanceOf(address(this)), days_vest * 4, "9");
hevm.warp(block.timestamp + 10 days);
assertEq(mVest.unpaid(id), days_vest * 10);
assertEq(mVest.accrued(id), days_vest * 14);
assertEq(mVest.unpaid(id), days_vest * 10, "10");
assertEq(mVest.accrued(id), days_vest * 14, "11");
mVest.vest(id);
assertEq(mVest.unpaid(id), 0);
assertEq(mVest.accrued(id), days_vest * 14);
assertEq(gem.balanceOf(address(this)), days_vest * 14);
assertEq(mVest.unpaid(id), 0, "12");
assertEq(mVest.accrued(id), days_vest * 14, "13");
assertEq(gem.balanceOf(address(this)), days_vest * 14, "14");
hevm.warp(block.timestamp + 120 days); // vesting complete
assertEq(mVest.unpaid(id), days_vest * 86);
assertEq(mVest.accrued(id), days_vest * 100);
assertEq(mVest.unpaid(id), days_vest * 86, "15");
assertEq(mVest.accrued(id), days_vest * 100, "16");
mVest.vest(id);
assertEq(gem.balanceOf(address(this)), 100 * days_vest);
assertEq(gem.balanceOf(address(this)), 100 * days_vest, "17");
}

function testFutureAccrual() public {
Expand Down Expand Up @@ -676,6 +696,24 @@ contract DssVestTest is DSTest {
assertEq(vat.sin(VOW), originalSin + 100 * days_vest * RAY);
}

function testSuckableVestUsds() public {
uint256 originalSin = vat.sin(VOW);
uint256 id = sVestUsds.create(address(this), 100 * days_vest, block.timestamp, 100 days, 0, address(0));
assertTrue(sVestUsds.valid(id));
hevm.warp(block.timestamp + 1 days);
sVestUsds.vest(id);
assertEq(usds.balanceOf(address(this)), 1 * days_vest);
assertEq(vat.sin(VOW), originalSin + 1 * days_vest * RAY);
hevm.warp(block.timestamp + 9 days);
sVestUsds.vest(id);
assertEq(usds.balanceOf(address(this)), 10 * days_vest);
assertEq(vat.sin(VOW), originalSin + 10 * days_vest * RAY);
hevm.warp(block.timestamp + 365 days);
sVestUsds.vest(id);
assertEq(usds.balanceOf(address(this)), 100 * days_vest);
assertEq(vat.sin(VOW), originalSin + 100 * days_vest * RAY);
}

function testSuckableVestCaged() public {
uint256 originalSin = vat.sin(VOW);
uint256 id = sVest.create(address(this), 100 * days_vest, block.timestamp, 100 days, 0, address(0));
Expand Down

0 comments on commit 59b0a51

Please sign in to comment.