Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 42 additions & 35 deletions packages/foundry/contracts/test/variable/Fixture.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ import "@yield-protocol/utils-v2/contracts/math/WMul.sol";
using CastU256I128 for uint256;
using CastU256I256 for uint256;
using WMul for uint256;

abstract contract Fixture is Test, TestConstants, TestExtensions {
address public admin = makeAddr("admin");
address public user = makeAddr("user");
address public immutable timelock;
VRCauldron public cauldron;
VRLadle public ladle;
Witch public witch;
Expand All @@ -64,8 +66,6 @@ abstract contract Fixture is Test, TestConstants, TestExtensions {
AccumulatorMultiOracle public chiRateOracle;
ChainlinkMultiOracle public spotOracle;
ChainlinkAggregatorV3Mock public ethAggregator;
ChainlinkAggregatorV3Mock public daiAggregator;
ChainlinkAggregatorV3Mock public usdcAggregator;
ChainlinkAggregatorV3Mock public baseAggregator;

bytes12 public vaultId = 0x000000000000000000000001;
Expand All @@ -80,10 +80,21 @@ abstract contract Fixture is Test, TestConstants, TestExtensions {
uint256 public ART = WAD;
uint256 public FEE = 1000;
uint128 public unit;

address USDC_JOIN = address(0x0d9A1A773be5a83eEbda23bf98efB8585C3ae4f4);
address DAI_JOIN = address(0x4fE92119CDf873Cf8826F4E6EcfD4E578E3D44Dc);
address WETH_JOIN = address(0x3bDb887Dc46ec0E964Df89fFE2980db0121f0fD0);

constructor(){
timelock = addresses[MAINNET][TIMELOCK];
}

function setUp() public virtual {
usdc = new USDCMock();
weth = new WETH9Mock();
dai = new DAIMock();
vm.createSelectFork(MAINNET, 16668354);

usdc = USDCMock(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);
weth = WETH9Mock(payable(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2));
dai = DAIMock(0x6B175474E89094C44Da98b954EedeAC495271d0F);
base = new ERC20Mock("Base", "BASE");
otherERC20 = new ERC20Mock("Other ERC20", "OTHERERC20");

Expand All @@ -93,17 +104,27 @@ abstract contract Fixture is Test, TestConstants, TestExtensions {
IWETH9(address(weth))
);
witch = new Witch(ICauldron(address(cauldron)), ILadle(address(ladle)));


restrictedERC20Mock = new RestrictedERC20Mock("Restricted", "RESTRICTED");

usdcJoin = new FlashJoin(address(usdc));
wethJoin = new FlashJoin(address(weth));
daiJoin = new FlashJoin(address(dai));
usdcJoin = FlashJoin(USDC_JOIN);
wethJoin = FlashJoin(WETH_JOIN);
daiJoin = FlashJoin(DAI_JOIN);

bytes4 role = 0x00000000;
vm.startPrank(timelock);
AccessControl access = AccessControl(address(usdcJoin));
access.grantRole(role, address(this));
access = AccessControl(address(wethJoin));
access.grantRole(role, address(this));
access = AccessControl(address(daiJoin));
access.grantRole(role, address(this));
vm.stopPrank();

baseJoin = new FlashJoin(address(base));

setUpOracles();
vyToken = new VYToken(baseId, IOracle(address(chiRateOracle)), IJoin(baseJoin),base.name(), base.symbol());
vyToken = new VYToken(daiId, IOracle(address(chiRateOracle)), IJoin(daiJoin),dai.name(), dai.symbol());
// Setting permissions
ladleGovAuth();
cauldronGovAuth(address(ladle));
Expand All @@ -115,12 +136,14 @@ abstract contract Fixture is Test, TestConstants, TestExtensions {
bytes4[] memory roles = new bytes4[](2);
roles[0] = Join.join.selector;
roles[1] = Join.exit.selector;
baseJoin.grantRoles(roles, address(vyToken));
vm.prank(timelock);
daiJoin.grantRoles(roles, address(vyToken));
}

function setUpOracles() internal {
chiRateOracle = new AccumulatorMultiOracle();
chiRateOracle = AccumulatorMultiOracle(0x95750d6F5fba4ed1cc4Dc42D2c01dFD3DB9a11eC);

vm.startPrank(timelock);
chiRateOracle.grantRole(
AccumulatorMultiOracle.setSource.selector,
address(this)
Expand All @@ -129,48 +152,32 @@ abstract contract Fixture is Test, TestConstants, TestExtensions {
AccumulatorMultiOracle.updatePerSecondRate.selector,
address(this)
);
vm.stopPrank();
chiRateOracle.setSource(baseId, RATE, WAD, WAD * 2);
chiRateOracle.setSource(baseId, CHI, WAD, WAD * 2);

ethAggregator = new ChainlinkAggregatorV3Mock();
ethAggregator.set(1e18 / 2);

daiAggregator = new ChainlinkAggregatorV3Mock();
daiAggregator.set(1e18 / 2);

usdcAggregator = new ChainlinkAggregatorV3Mock();
usdcAggregator.set(1e18 / 2);

baseAggregator = new ChainlinkAggregatorV3Mock();
baseAggregator.set(1e18 / 2);

spotOracle = new ChainlinkMultiOracle();
spotOracle = ChainlinkMultiOracle(0xcDCe5C87f691058B61f3A65913f1a3cBCbAd9F52);

bytes4 role = 0x00000000;
AccessControl access = AccessControl(address(spotOracle));
vm.prank(timelock);
spotOracle.grantRole(
ChainlinkMultiOracle.setSource.selector,
address(this)
);

spotOracle.setSource(
ETH,
IERC20Metadata(address(weth)),
usdcId,
IERC20Metadata(address(usdc)),
address(usdcAggregator)
);
spotOracle.setSource(
ETH,
IERC20Metadata(address(weth)),
baseId,
IERC20Metadata(address(base)),
address(ethAggregator)
);
spotOracle.setSource(
ETH,
IERC20Metadata(address(weth)),
daiId,
IERC20Metadata(address(dai)),
address(daiAggregator)
);
}

// ----------------- Permissions ----------------- //
Expand Down Expand Up @@ -241,7 +248,7 @@ abstract contract Fixture is Test, TestConstants, TestExtensions {
18
);
(bytes12 vaultId_,) = ladle.build(assetId, assetId, salt);
// cauldron.build(address(this), vaultId_, assetId, assetId);

IERC20(assetAddress).approve(address(join),INK * 10);
deal(assetAddress, address(this), INK * 10);
ladle.pour(vaultId_, address(this), (INK * 10).i128(), 0);
Expand Down
4 changes: 1 addition & 3 deletions packages/foundry/contracts/test/variable/FixtureStates.sol
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,11 @@ abstract contract ETHVaultPouredAndDebtState is ETHVaultPouredState {
}
}

abstract contract VYTokenZeroState is ZeroState {
address public timelock;
abstract contract VYTokenZeroState is CompleteSetup {
FlashBorrower public borrower;

function setUp() public virtual override {
super.setUp();
timelock = address(1);
vyToken.grantRole(VYToken.point.selector, address(timelock));
vyToken.grantRole(VYToken.mint.selector, address(this));
vyToken.grantRole(VYToken.deposit.selector, address(this));
Expand Down
14 changes: 6 additions & 8 deletions packages/foundry/contracts/test/variable/VRCauldron.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,6 @@ contract CauldronTestOnBuiltVault is VaultBuiltState {
);

// Adding new base and ilks to it
chiRateOracle.setSource(daiId, RATE, WAD, WAD * 2);
chiRateOracle.setSource(daiId, CHI, WAD, WAD * 2);
makeBase(daiId, address(dai), daiJoin, address(chiRateOracle), 12);
cauldron.setSpotOracle(daiId, usdcId, spotOracle, 1000000);
cauldron.setSpotOracle(daiId, wethId, spotOracle, 1000000);
Expand Down Expand Up @@ -452,25 +450,25 @@ contract FuzzLevelTestsOnBorrowedState is BorrowedState {

function testFuzz_levelGoesDownAsPriceGoesUp(int256 price) public {
vm.assume(price > 0);
(, bytes6 baseId, ) = cauldron.vaults(vaultId);
(, int256 currentPrice, , ,) = usdcAggregator.latestRoundData();
(, bytes6 baseId, bytes6 ilkId) = cauldron.vaults(vaultId);
(, int256 currentPrice, , ,) = ethAggregator.latestRoundData();

// Level goes down as price goes up
vm.assume(price > currentPrice);
int256 startLevel = cauldron.level(vaultId);
usdcAggregator.set(uint256(price));
ethAggregator.set(uint256(price));
assertGt(startLevel,cauldron.level(vaultId));
}

function testFuzz_levelGoesupAsPriceGoesDown(int256 price) public {
// Level goes up as price goes down
vm.assume(price > 0);
(, bytes6 baseId, ) = cauldron.vaults(vaultId);
(, int256 currentPrice, , ,) = usdcAggregator.latestRoundData();
(, int256 currentPrice, , ,) = ethAggregator.latestRoundData();

vm.assume(price < currentPrice);
int256 startLevel = cauldron.level(vaultId);
usdcAggregator.set(uint256(price));
ethAggregator.set(uint256(price));
console.logInt(startLevel);
console.logInt(cauldron.level(vaultId));
assertLt(startLevel,cauldron.level(vaultId));
Expand Down
22 changes: 13 additions & 9 deletions packages/foundry/contracts/test/variable/VRLadle.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -583,21 +583,23 @@ contract TokensAndIntegrationTests is WithTokensAndIntegrationState {
contract ETHTests is ETHVaultBuiltState {
function testCanTransferETHThenPour() public {
console.log("can transfer eth and then pour");
uint before = weth.balanceOf(address(ladle.joins(wethId)));
ladle.joinEther{value: INK}(wethId);
vm.expectEmit(true, true, true, true);
emit VaultPoured(ethVaultId, baseId, wethId, INK.i128(), 0);
ladle.pour(ethVaultId, address(this), INK.i128(), 0);

assertEq(weth.balanceOf(address(ladle.joins(wethId))), INK);
assertEq(weth.balanceOf(address(ladle.joins(wethId))) - before, INK);
(uint128 art, uint128 ink) = cauldron.balances(ethVaultId);
assertEq(ink, INK);
assertEq(art, 0);
}

function testPourWithoutSendingETHReverts() public {
console.log("pour without sending eth reverts");
weth.approve(address(wethJoin), 0 );
vm.expectRevert("ERC20: Insufficient approval");
weth.approve(address(wethJoin), 0);
// Since weth doesn't have a error message for insufficient allowance https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code#L70
vm.expectRevert("Transaction reverted silently");
ladle.pour(ethVaultId, address(this), INK.i128(), 0);
}

Expand All @@ -609,9 +611,10 @@ contract ETHTests is ETHVaultBuiltState {

vm.expectEmit(true, true, true, true);
emit VaultPoured(ethVaultId, baseId, wethId, INK.i128(), 0);
uint before = weth.balanceOf(address(ladle.joins(wethId)));
ladle.batch{ value: INK}(calls);

assertEq(weth.balanceOf(address(ladle.joins(wethId))), INK);
assertEq(weth.balanceOf(address(ladle.joins(wethId))) - before, INK);
(uint128 art, uint128 ink) = cauldron.balances(ethVaultId);
assertEq(ink, INK);
assertEq(art, 0);
Expand All @@ -627,11 +630,12 @@ contract ETHTests is ETHVaultBuiltState {
contract ETHVaultPouredStateTest is ETHVaultPouredState {
function testPourToWithdraw() public {
console.log("can pour to withdraw");
ladle.pour(ethVaultId, address(this), -INK.i128(), 0);
(uint128 art, uint128 ink) = cauldron.balances(ethVaultId);
ladle.pour(ethVaultId, address(this), -int128(ink), 0);

assertEq(weth.balanceOf(address(ladle.joins(wethId))), 0);
// assertEq(weth.balanceOf(address(ladle.joins(wethId))), 0);
assertEq(weth.balanceOf(address(this)), INK);
(uint128 art, uint128 ink) = cauldron.balances(ethVaultId);
( art, ink) = cauldron.balances(ethVaultId);
assertEq(ink, 0);
assertEq(art, 0);
}
Expand All @@ -642,10 +646,10 @@ contract ETHVaultPouredStateTest is ETHVaultPouredState {
bytes[] memory calls = new bytes[](2);
calls[0] = abi.encodeWithSelector(VRLadle.pour.selector, ethVaultId, address(ladle), -INK.i128(), 0);
calls[1] = abi.encodeWithSelector(VRLadle.exitEther.selector, address(this));

uint before = weth.balanceOf(address(ladle.joins(wethId)));
ladle.batch(calls);

assertEq(weth.balanceOf(address(ladle.joins(wethId))), 0);
assertEq(before - INK - weth.balanceOf(address(ladle.joins(wethId))), 0);
assertEq(weth.balanceOf(address(this)), 0);
(uint128 art, uint128 ink) = cauldron.balances(ethVaultId);
assertEq(ink, 0);
Expand Down
4 changes: 2 additions & 2 deletions packages/foundry/contracts/test/variable/VYToken.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ contract VYTokenTest is VYTokenZeroState {
vyToken.underlyingId(),
CHI
);

vm.assume(newRate > oldPerSecondRate);
newRate = uint128(bound(newRate, oldPerSecondRate, type(uint128).max));
chiRateOracle.updatePerSecondRate(vyToken.underlyingId(), CHI, newRate);
vm.warp(block.timestamp + 1);
Expand Down Expand Up @@ -226,7 +226,7 @@ contract VYTokenTest is VYTokenZeroState {
vyToken.underlyingId(),
CHI
);

vm.assume(newRate > oldPerSecondRate);
newRate = uint128(bound(newRate, oldPerSecondRate, type(uint128).max));
chiRateOracle.updatePerSecondRate(vyToken.underlyingId(), CHI, newRate);
vm.warp(block.timestamp + 1);
Expand Down
11 changes: 7 additions & 4 deletions packages/foundry/contracts/variable/VRCauldron.sol
Original file line number Diff line number Diff line change
Expand Up @@ -407,9 +407,12 @@ contract VRCauldron is AccessControl, Constants {
) = vaultData(vaultId);

// Normalize the base amount to debt terms
int128 art = base > 0
? _debtFromBase(vault_.baseId, base.u128()).i128()
: -_debtFromBase(vault_.baseId, (-base).u128()).i128();
int128 art = base;

if (base != 0)
art = base > 0
? _debtFromBase(vault_.baseId, base.u128()).i128()
: -_debtFromBase(vault_.baseId, (-base).u128()).i128();

balances_ = _pour(vaultId, vault_, balances_, ink, art);

Expand Down Expand Up @@ -468,4 +471,4 @@ contract VRCauldron is AccessControl, Constants {
uint256 baseValue = _debtToBase(vault_.baseId, balances_.art); // art * rate
return inkValue.i256() - baseValue.wmul(ratio).i256();
}
}
}