From 8ce84c9fe71d7601e9cbf2efc2d06c9d6a149488 Mon Sep 17 00:00:00 2001 From: magic990619 Date: Sat, 21 May 2022 03:14:45 +1000 Subject: [PATCH] aUSTVault --- .gitignore | 2 + contracts/src/integrations/aUSTVault.sol | 30 ++++- contracts/src/interfaces/IAnchorRouter.sol | 7 ++ contracts/test/aUSTVault.t.sol | 140 +++++++++++++++++++++ 4 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 .gitignore create mode 100644 contracts/src/interfaces/IAnchorRouter.sol create mode 100644 contracts/test/aUSTVault.t.sol diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a69ecc --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +contracts/out +contracts/cache diff --git a/contracts/src/integrations/aUSTVault.sol b/contracts/src/integrations/aUSTVault.sol index c054e21..4f3fa94 100755 --- a/contracts/src/integrations/aUSTVault.sol +++ b/contracts/src/integrations/aUSTVault.sol @@ -2,10 +2,18 @@ pragma solidity 0.8.10; import "src/Vault.sol"; +import {IAnchorRouter} from "src/interfaces/IAnchorRouter.sol"; - +/** + * @notice aUSTVault is the vault token for UST token rewards. + * It collects rewards from the anchor router and distributes them to the + * swap so that it can autocompound. + */ contract aUSTVault is Vault { + IAnchorRouter public router; + address public aUST = 0xaB9A04808167C170A9EC4f8a87a0cD781ebcd55e; + function initialize( address _underlying, string memory _name, @@ -13,7 +21,8 @@ contract aUSTVault is Vault { uint256 _adminFee, uint256 _callerFee, uint256 _maxReinvestStale, - address _WAVAX + address _WAVAX, + address _router ) public { initialize(_underlying, _name, @@ -23,7 +32,20 @@ contract aUSTVault is Vault { _maxReinvestStale, _WAVAX ); - // TODO: Change this initializer as necessary + + router = IAnchorRouter(_router); + underlying.approve(_router, MAX_INT); + } + + function _triggerDepositAction(uint256 _amt) internal override { + router.depositStable(_amt); + } + + function _triggerWithdrawAction(uint256 amtToReturn) internal override { + router.redeemStable(amtToReturn); + } + + function _pullRewards() internal override { + router.redeemStable(IERC20(aUST).balanceOf(address(this))); } - // TODO: Override functions and add helpers as necessary } diff --git a/contracts/src/interfaces/IAnchorRouter.sol b/contracts/src/interfaces/IAnchorRouter.sol new file mode 100644 index 0000000..089fc5d --- /dev/null +++ b/contracts/src/interfaces/IAnchorRouter.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +interface IAnchorRouter { + function depositStable(uint256 _amount) external; + function redeemStable(uint256 _amount) external; +} \ No newline at end of file diff --git a/contracts/test/aUSTVault.t.sol b/contracts/test/aUSTVault.t.sol new file mode 100644 index 0000000..93b24d6 --- /dev/null +++ b/contracts/test/aUSTVault.t.sol @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.10; + +import "ds-test/test.sol"; +import "forge-std/console.sol"; +import "forge-std/stdlib.sol"; +import "forge-std/Vm.sol"; +import "src/integrations/aUSTVault.sol"; +import "./TestERC20.sol"; +import "./Utils.sol"; + + +// This test covers integration for comp-like vaults + +contract TestsaUSTVault is DSTest { + + uint constant ADMINFEE=100; + uint constant CALLERFEE=10; + uint constant MAX_REINVEST_STALE= 1 hours; + uint constant MAX_INT= 2**256 - 1; + Vm public constant vm = Vm(HEVM_ADDRESS); + + IERC20 constant WAVAX = IERC20(0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7); //WAVAX + address constant wavaxHolder = 0xBBff2A8ec8D702E61faAcCF7cf705968BB6a5baB; + + IERC20 constant UST = IERC20(0xb599c3590F42f8F995ECfa0f85D2980B76862fc1); //UST + IERC20 constant aUST = IERC20(0xaB9A04808167C170A9EC4f8a87a0cD781ebcd55e); //aUST + address constant USTHolder = 0x218Eb2694357FD7Dfd79Da8eeefF3049c4fbaC4E; + + address constant joePair = 0xA389f9430876455C36478DeEa9769B7Ca4E3DDB1; // USDC-WAVAX + address constant joeRouter = 0x60aE616a2155Ee3d9A68541Ba4544862310933d4; + address constant aave = 0x4F01AeD16D97E3aB5ab2B501154DC9bb0F1A5A2C; + address constant aaveV3 = 0x794a61358D6845594F94dc1DB02A252b5b4814aD; + + aUSTVault public vault; + uint public underlyingBalance; + function setUp() public { + vault = new aUSTVault(); + vault.initialize( + address(UST), + "Vault", + "VAULT", + ADMINFEE, + CALLERFEE, + MAX_REINVEST_STALE, + address(WAVAX), + 0xcEF9E167d3f8806771e9bac1d4a0d568c39a9388); + + vault.setJoeRouter(joeRouter); + vault.setAAVE(aave, aaveV3); + vault.setApprovals(address(WAVAX), joeRouter, MAX_INT); + vault.setApprovals(address(UST), joeRouter, MAX_INT); + + vault.setApprovals(address(WAVAX), aave, MAX_INT); + vault.setApprovals(address(UST), aave, MAX_INT); + vault.setApprovals(address(UST), 0xcEF9E167d3f8806771e9bac1d4a0d568c39a9388, MAX_INT); + + vm.startPrank(wavaxHolder); + WAVAX.transfer(address(this), WAVAX.balanceOf(wavaxHolder)); + vm.stopPrank(); + vm.startPrank(USTHolder); + UST.transfer(address(this), UST.balanceOf(USTHolder)); + vm.stopPrank(); + + vault.pushRewardToken(address(WAVAX)); + vault.pushRewardToken(address(UST)); + + UST.approve(address(vault), MAX_INT); + underlyingBalance=UST.balanceOf(address(this)); + vm.warp(1647861775-80 days); + } + + + function testVanillaDeposit(uint96 amt) public returns (uint) { + // uint amt = 1e18; + if (amt > underlyingBalance || amt underlyingBalance || amt underlyingBalance || amt underlyingBalance || amt<1e5*vault.MIN_FIRST_MINT()) { + return 0; + } + vault.deposit(amt); + uint preBalance = vault.underlyingPerReceipt(); + vm.warp(block.timestamp+100 days); + vault.compound(); + uint postBalance = vault.underlyingPerReceipt(); + assertTrue(postBalance > preBalance); + return amt; + } + function testVanillaDepositNCompoundredeem(uint96 amt) public returns (uint) { + // uint amt = 1e18; + if (amt > underlyingBalance || amt