Skip to content

Latest commit

 

History

History
625 lines (497 loc) · 16.9 KB

AaveStrategy.md

File metadata and controls

625 lines (497 loc) · 16.9 KB

AaveStrategy.sol

View Source: contracts/core/liquidity/strategies/AaveStrategy.sol

↗ Extends: ILendingStrategy, Recoverable ↘ Derived Contracts: InvalidStrategy

AaveStrategy

Contract Members

Constants & Variables

//public members
bytes32 public constant CNAME_STRATEGY_AAVE;
bytes32 public constant NS_DEPOSITS;
bytes32 public constant NS_WITHDRAWALS;
address public depositCertificate;
contract IAaveV2LendingPoolLike public lendingPool;

//private members
bytes32 private constant _KEY;
mapping(bytes32 => uint256) private _counters;
mapping(bytes32 => uint256) private _depositTotal;
mapping(bytes32 => uint256) private _withdrawalTotal;

Functions

function (IStore _s, IAaveV2LendingPoolLike _lendingPool, address _aToken) public nonpayable Recoverable 

Arguments

Name Type Description
_s IStore
_lendingPool IAaveV2LendingPoolLike
_aToken address
Source Code
constructor(
    IStore _s,
    IAaveV2LendingPoolLike _lendingPool,
    address _aToken
  ) Recoverable(_s) {
    depositCertificate = _aToken;
    lendingPool = _lendingPool;
  }

getDepositAsset

function getDepositAsset() public view
returns(contract IERC20)

Arguments

Name Type Description
Source Code
function getDepositAsset() public view override returns (IERC20) {
    return IERC20(s.getStablecoinAddressInternal());
  }

getDepositCertificate

function getDepositCertificate() public view
returns(contract IERC20)

Arguments

Name Type Description
Source Code
function getDepositCertificate() public view override returns (IERC20) {
    return IERC20(depositCertificate);
  }

_drain

function _drain(IERC20 asset) private nonpayable

Arguments

Name Type Description
asset IERC20
Source Code
function _drain(IERC20 asset) private {
    uint256 amount = asset.balanceOf(address(this));

    if (amount > 0) {
      asset.ensureTransfer(s.getTreasuryAddressInternal(), amount);
      emit Drained(asset, amount);
    }
  }

getInfo

Gets info of this strategy by cover key Warning: this function does not validate the cover key supplied.

function getInfo(bytes32 coverKey) external view
returns(info struct ILendingStrategy.LendingStrategyInfoType)

Arguments

Name Type Description
coverKey bytes32 Enter the cover key
Source Code
function getInfo(bytes32 coverKey) external view override returns (LendingStrategyInfoType memory info) {
    info.deposits = s.getUintByKey(_getDepositsKey(coverKey));
    info.withdrawals = s.getUintByKey(_getWithdrawalsKey(coverKey));
  }

_getCertificateBalance

function _getCertificateBalance() private view
returns(uint256)

Arguments

Name Type Description
Source Code
function _getCertificateBalance() private view returns (uint256) {
    return getDepositCertificate().balanceOf(address(this));
  }

deposit

Lends stablecoin to the Aave protocol Ensure that you approve stablecoin before you call this function

function deposit(bytes32 coverKey, uint256 amount) external nonpayable nonReentrant 
returns(aTokenReceived uint256)

Arguments

Name Type Description
coverKey bytes32
amount uint256
Source Code
function deposit(bytes32 coverKey, uint256 amount) external override nonReentrant returns (uint256 aTokenReceived) {
    s.mustNotBePaused();
    s.senderMustBeProtocolMember();

    IVault vault = s.getVault(coverKey);

    if (amount == 0) {
      return 0;
    }

    IERC20 stablecoin = getDepositAsset();
    IERC20 aToken = getDepositCertificate();

    require(stablecoin.balanceOf(address(vault)) >= amount, "Balance insufficient");

    // This strategy should never have token balances without any exception, especially `aToken` and `stablecoin`
    _drain(aToken);
    _drain(stablecoin);

    // Transfer stablecoin to this contract; then approve and deposit it to Aave Lending Pool to receive aToken certificates
    // stablecoin.ensureTransferFrom(fromVault, address(this), amount);

    vault.transferToStrategy(stablecoin, coverKey, getName(), amount);
    stablecoin.ensureApproval(address(lendingPool), amount);
    lendingPool.deposit(address(getDepositAsset()), amount, address(this), 0);

    // Check how many aTokens we received
    aTokenReceived = _getCertificateBalance();
    require(aTokenReceived > 0, "Deposit to Aave failed");

    // Immediately send aTokens to the original vault stablecoin came from
    aToken.ensureApproval(address(vault), aTokenReceived);
    vault.receiveFromStrategy(aToken, coverKey, getName(), aTokenReceived);

    s.addUintByKey(_getDepositsKey(coverKey), amount);

    _counters[coverKey] += 1;
    _depositTotal[coverKey] += amount;

    emit LogDeposit(getName(), _counters[coverKey], amount, aTokenReceived, _depositTotal[coverKey], _withdrawalTotal[coverKey]);
    emit Deposited(coverKey, address(vault), amount, aTokenReceived);
  }

withdraw

Redeems aToken from Aave to receive stablecoin Ensure that you approve aToken before you call this function

function withdraw(bytes32 coverKey) external nonpayable nonReentrant 
returns(stablecoinWithdrawn uint256)

Arguments

Name Type Description
coverKey bytes32
Source Code
function withdraw(bytes32 coverKey) external virtual override nonReentrant returns (uint256 stablecoinWithdrawn) {
    s.mustNotBePaused();
    s.senderMustBeProtocolMember();

    IVault vault = s.getVault(coverKey);

    IERC20 stablecoin = getDepositAsset();
    IERC20 aToken = getDepositCertificate();

    // This strategy should never have token balances
    _drain(aToken);
    _drain(stablecoin);

    uint256 aTokenRedeemed = aToken.balanceOf(address(vault));

    if (aTokenRedeemed == 0) {
      return 0;
    }

    // Transfer aToken to this contract; then approve and send it to the Aave Lending pool get back stablecoin + rewards
    vault.transferToStrategy(aToken, coverKey, getName(), aTokenRedeemed);

    aToken.ensureApproval(address(lendingPool), aTokenRedeemed);
    lendingPool.withdraw(address(stablecoin), aTokenRedeemed, address(this));

    // Check how many stablecoins we received
    stablecoinWithdrawn = stablecoin.balanceOf(address(this));

    require(stablecoinWithdrawn > 0, "Redeeming aToken failed");

    // Immediately send stablecoin to the vault aToken came from
    stablecoin.ensureApproval(address(vault), stablecoinWithdrawn);
    vault.receiveFromStrategy(stablecoin, coverKey, getName(), stablecoinWithdrawn);

    s.addUintByKey(_getWithdrawalsKey(coverKey), stablecoinWithdrawn);

    _counters[coverKey] += 1;
    _withdrawalTotal[coverKey] += stablecoinWithdrawn;

    emit LogWithdrawal(getName(), _counters[coverKey], stablecoinWithdrawn, aTokenRedeemed, _depositTotal[coverKey], _withdrawalTotal[coverKey]);
    emit Withdrawn(coverKey, address(vault), stablecoinWithdrawn, aTokenRedeemed);
  }

_getDepositsKey

Hash key of the Aave deposits for the given cover. Warning: this function does not validate the cover key supplied.

function _getDepositsKey(bytes32 coverKey) private pure
returns(bytes32)

Arguments

Name Type Description
coverKey bytes32 Enter cover key
Source Code
function _getDepositsKey(bytes32 coverKey) private pure returns (bytes32) {
    return keccak256(abi.encodePacked(_KEY, coverKey, NS_DEPOSITS));
  }

_getWithdrawalsKey

Hash key of the Aave withdrawals for the given cover. Warning: this function does not validate the cover key supplied.

function _getWithdrawalsKey(bytes32 coverKey) private pure
returns(bytes32)

Arguments

Name Type Description
coverKey bytes32 Enter cover key
Source Code
function _getWithdrawalsKey(bytes32 coverKey) private pure returns (bytes32) {
    return keccak256(abi.encodePacked(_KEY, coverKey, NS_WITHDRAWALS));
  }

getWeight

function getWeight() external pure
returns(uint256)

Arguments

Name Type Description
Source Code
function getWeight() external pure virtual override returns (uint256) {
    return 10_000; // 100%
  }

getKey

function getKey() external pure
returns(bytes32)

Arguments

Name Type Description
Source Code
function getKey() external pure override returns (bytes32) {
    return _KEY;
  }

version

Version number of this contract

function version() external pure
returns(bytes32)

Arguments

Name Type Description
Source Code
function version() external pure override returns (bytes32) {
    return "v0.1";
  }

getName

Name of this contract

function getName() public pure
returns(bytes32)

Arguments

Name Type Description
Source Code
function getName() public pure override returns (bytes32) {
    return CNAME_STRATEGY_AAVE;
  }

Contracts