├── .node-version ├── doc └── diagram_ForceDAO.jpg ├── migrations ├── 2_deploy_FishToken.js ├── 1_initial_migration.js ├── addressesList │ ├── contractAddress │ │ └── contractAddress.js │ └── tokenAddress │ │ └── tokenAddress.js ├── 5_deploy_YieldFarmingStrategyFactory.js └── 3_deploy_MasterChef.js ├── .env.example ├── contracts ├── mock-token │ ├── ForceSend.sol │ └── DAIMockToken.sol ├── aave-v2 │ ├── interfaces │ │ ├── IDelegationToken.sol │ │ ├── IERC20WithPermit.sol │ │ ├── IPriceOracleGetter.sol │ │ ├── IPriceOracle.sol │ │ ├── IExchangeAdapter.sol │ │ ├── IUniswapExchange.sol │ │ ├── IChainlinkAggregator.sol │ │ ├── ILendingRateOracle.sol │ │ ├── IUniswapV2Router02.sol │ │ ├── ICreditDelegationToken.sol │ │ ├── IScaledBalanceToken.sol │ │ ├── ILendingPoolAddressesProviderRegistry.sol │ │ ├── IReserveInterestRateStrategy.sol │ │ ├── IInitializableDebtToken.sol │ │ ├── IInitializableAToken.sol │ │ ├── IVariableDebtToken.sol │ │ ├── ILendingPoolCollateralManager.sol │ │ ├── ILendingPoolAddressesProvider.sol │ │ ├── IAToken.sol │ │ ├── IAaveIncentivesController.sol │ │ ├── IStableDebtToken.sol │ │ └── ILendingPoolConfigurator.sol │ ├── dependencies │ │ └── openzeppelin │ │ │ ├── contracts │ │ │ ├── IERC20Detailed.sol │ │ │ ├── Context.sol │ │ │ ├── SafeERC20.sol │ │ │ ├── Ownable.sol │ │ │ ├── Address.sol │ │ │ ├── IERC20.sol │ │ │ └── SafeMath.sol │ │ │ └── upgradeability │ │ │ ├── UpgradeabilityProxy.sol │ │ │ ├── InitializableUpgradeabilityProxy.sol │ │ │ ├── AdminUpgradeabilityProxy.sol │ │ │ ├── InitializableAdminUpgradeabilityProxy.sol │ │ │ ├── BaseUpgradeabilityProxy.sol │ │ │ ├── Initializable.sol │ │ │ ├── Proxy.sol │ │ │ └── BaseAdminUpgradeabilityProxy.sol │ ├── flashloan │ │ ├── interfaces │ │ │ └── IFlashLoanReceiver.sol │ │ └── base │ │ │ └── FlashLoanReceiverBase.sol │ └── protocol │ │ ├── libraries │ │ ├── aave-upgradeability │ │ │ ├── InitializableImmutableAdminUpgradeabilityProxy.sol │ │ │ ├── VersionedInitializable.sol │ │ │ └── BaseImmutableAdminUpgradeabilityProxy.sol │ │ ├── helpers │ │ │ └── Helpers.sol │ │ ├── types │ │ │ └── DataTypes.sol │ │ ├── math │ │ │ ├── PercentageMath.sol │ │ │ ├── MathUtils.sol │ │ │ └── WadRayMath.sol │ │ └── configuration │ │ │ └── UserConfiguration.sol │ │ ├── tokenization │ │ ├── DelegationAwareAToken.sol │ │ ├── base │ │ │ └── DebtTokenBase.sol │ │ └── VariableDebtToken.sol │ │ ├── lendingpool │ │ └── LendingPoolStorage.sol │ │ └── configuration │ │ ├── LendingPoolAddressesProviderRegistry.sol │ │ └── LendingPoolAddressesProvider.sol ├── polycat │ └── Farm │ │ ├── Governor.sol │ │ ├── libs │ │ └── IReferral.sol │ │ ├── Operators.sol │ │ ├── Referral.sol │ │ ├── IFO.sol │ │ └── Timelock.sol ├── Migrations.sol ├── commons │ └── yield-farming-strategy │ │ └── YieldFarmingStrategyCommons.sol └── YieldFarmingStrategyFactory.sol ├── test └── test-local │ ├── truffle-mint-dai │ ├── utils.js │ ├── dai.js │ ├── sai.js │ ├── usdt.js │ ├── usdc.js │ └── abi │ │ ├── usdt-abi.js │ │ ├── usdc-abi.js │ │ ├── dai.js │ │ └── erc20.js │ ├── web3js-helper │ └── web3jsHelper.js │ └── YieldFarmingStrategy.test.js ├── .editorconfig ├── migrations_archive └── 4_deploy_YieldFarmingStrategy.js ├── scripts └── web3js-helper │ └── web3jsHelper.js ├── package.json ├── truffle-config.js ├── .gitignore └── README.md /.node-version: -------------------------------------------------------------------------------- 1 | 15.14.0 2 | -------------------------------------------------------------------------------- /doc/diagram_ForceDAO.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masaun/forceDAO-yield-farming-strategy-on-polygon/HEAD/doc/diagram_ForceDAO.jpg -------------------------------------------------------------------------------- /migrations/2_deploy_FishToken.js: -------------------------------------------------------------------------------- 1 | const FishToken = artifacts.require("FishToken") 2 | 3 | module.exports = async function(deployer) { 4 | await deployer.deploy(FishToken) 5 | } 6 | -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | const Migrations = artifacts.require("Migrations") 2 | 3 | module.exports = async function(deployer) { 4 | await deployer.deploy(Migrations) 5 | }; 6 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | MNEMONIC="Please input the mnemonic of your wallet into here" 2 | INFURA_KEY="Please input your infura key into here" 3 | DEPLOYER_ADDRESS="Please input your infura key into here" 4 | -------------------------------------------------------------------------------- /contracts/mock-token/ForceSend.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | // For test suite 4 | contract ForceSend { 5 | function go(address payable victim) external payable { 6 | selfdestruct(victim); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/test-local/truffle-mint-dai/utils.js: -------------------------------------------------------------------------------- 1 | module.exports.asyncForEach = async (array, callback) => { 2 | for (let index = 0; index < array.length; index++) { 3 | await callback(array[index], index, array); 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IDelegationToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | /** 5 | * @title IDelegationToken 6 | * @dev Implements an interface for tokens with delegation COMP/UNI compatible 7 | * @author Aave 8 | **/ 9 | interface IDelegationToken { 10 | function delegate(address delegatee) external; 11 | } 12 | -------------------------------------------------------------------------------- /contracts/mock-token/DAIMockToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.6.12; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | contract DAIMockToken is ERC20 { 7 | constructor() public ERC20("DAI Mock Token", "DAI") { 8 | uint256 initialSupply = 1e8 * 1e18; /// 1 milion 9 | _mint(msg.sender, initialSupply); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /contracts/polycat/Farm/Governor.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | contract Governor { 6 | address public govAddress; 7 | 8 | modifier onlyGov() { 9 | require(msg.sender == govAddress, "!gov"); 10 | _; 11 | } 12 | 13 | function setGov(address _govAddress) external onlyGov { 14 | govAddress = _govAddress; 15 | } 16 | } -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/contracts/IERC20Detailed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {IERC20} from './IERC20.sol'; 5 | 6 | interface IERC20Detailed is IERC20 { 7 | function name() external view returns (string memory); 8 | 9 | function symbol() external view returns (string memory); 10 | 11 | function decimals() external view returns (uint8); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IERC20WithPermit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; 5 | 6 | interface IERC20WithPermit is IERC20 { 7 | function permit( 8 | address owner, 9 | address spender, 10 | uint256 value, 11 | uint256 deadline, 12 | uint8 v, 13 | bytes32 r, 14 | bytes32 s 15 | ) external; 16 | } 17 | -------------------------------------------------------------------------------- /contracts/polycat/Farm/libs/IReferral.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | interface IReferral { 6 | /** 7 | * @dev Record referral. 8 | */ 9 | function recordReferral(address user, address referrer) external; 10 | 11 | /** 12 | * @dev Get the referrer address that referred the user. 13 | */ 14 | function getReferrer(address user) external view returns (address); 15 | } 16 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IPriceOracleGetter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | /** 5 | * @title IPriceOracleGetter interface 6 | * @notice Interface for the Aave price oracle. 7 | **/ 8 | 9 | interface IPriceOracleGetter { 10 | /** 11 | * @dev returns the asset price in ETH 12 | * @param asset the address of the asset 13 | * @return the ETH price of the asset 14 | **/ 15 | function getAssetPrice(address asset) external view returns (uint256); 16 | } 17 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IPriceOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | /************ 5 | @title IPriceOracle interface 6 | @notice Interface for the Aave price oracle.*/ 7 | interface IPriceOracle { 8 | /*********** 9 | @dev returns the asset price in ETH 10 | */ 11 | function getAssetPrice(address asset) external view returns (uint256); 12 | 13 | /*********** 14 | @dev sets the asset price, in wei 15 | */ 16 | function setAssetPrice(address asset, uint256 price) external; 17 | } 18 | -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.0 <0.7.0; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | constructor() public { 8 | owner = msg.sender; 9 | } 10 | 11 | modifier restricted() { 12 | if (msg.sender == owner) _; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IExchangeAdapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; 5 | 6 | interface IExchangeAdapter { 7 | event Exchange( 8 | address indexed from, 9 | address indexed to, 10 | address indexed platform, 11 | uint256 fromAmount, 12 | uint256 toAmount 13 | ); 14 | 15 | function approveExchange(IERC20[] calldata tokens) external; 16 | 17 | function exchange( 18 | address from, 19 | address to, 20 | uint256 amount, 21 | uint256 maxSlippage 22 | ) external returns (uint256); 23 | } 24 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IUniswapExchange.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | interface IUniswapExchange { 5 | event TokenPurchase( 6 | address indexed buyer, 7 | uint256 indexed eth_sold, 8 | uint256 indexed tokens_bought 9 | ); 10 | event EthPurchase(address indexed buyer, uint256 indexed tokens_sold, uint256 indexed eth_bought); 11 | event AddLiquidity( 12 | address indexed provider, 13 | uint256 indexed eth_amount, 14 | uint256 indexed token_amount 15 | ); 16 | event RemoveLiquidity( 17 | address indexed provider, 18 | uint256 indexed eth_amount, 19 | uint256 indexed token_amount 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IChainlinkAggregator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | interface IChainlinkAggregator { 5 | function latestAnswer() external view returns (int256); 6 | 7 | function latestTimestamp() external view returns (uint256); 8 | 9 | function latestRound() external view returns (uint256); 10 | 11 | function getAnswer(uint256 roundId) external view returns (int256); 12 | 13 | function getTimestamp(uint256 roundId) external view returns (uint256); 14 | 15 | event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 timestamp); 16 | event NewRound(uint256 indexed roundId, address indexed startedBy); 17 | } 18 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/ILendingRateOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | /** 5 | * @title ILendingRateOracle interface 6 | * @notice Interface for the Aave borrow rate oracle. Provides the average market borrow rate to be used as a base for the stable borrow rate calculations 7 | **/ 8 | 9 | interface ILendingRateOracle { 10 | /** 11 | @dev returns the market borrow rate in ray 12 | **/ 13 | function getMarketBorrowRate(address asset) external view returns (uint256); 14 | 15 | /** 16 | @dev sets the market borrow rate. Rate value must be in ray 17 | **/ 18 | function setMarketBorrowRate(address asset, uint256 rate) external; 19 | } 20 | -------------------------------------------------------------------------------- /migrations/addressesList/contractAddress/contractAddress.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "Polygon Mainnet": { 3 | "AAVE": { 4 | } 5 | }, 6 | "Polygon Mumbai": { 7 | "AAVE": { 8 | "LendingPoolAddressesProvider": "0x178113104fEcbcD7fF8669a0150721e231F0FD4B", 9 | "LendingPool": "0x9198F13B08E299d85E096929fA9781A1E3d5d827", 10 | "IncentivesController": "0xd41aE58e803Edf4304334acCE4DC4Ec34a63C644" 11 | }, 12 | "Polycat": { 13 | "MasterChef": "0x203D646B6d228E83aff613f9f04D59e63ab2C5d4" 14 | }, 15 | "ForceDAOYieldFarmingStrategy": { 16 | "YieldFarmingStrategyFactory": "0xCdf34b8d1A739c463AD318Ba94ae735dCc277a08" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /migrations/addressesList/tokenAddress/tokenAddress.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "Polygon Mainnet": { 3 | }, 4 | "Polygon Mumbai": { 5 | "AAVE": { 6 | "variableDebtmDAI": "0x6D29322ba6549B95e98E9B08033F5ffb857f19c5" 7 | }, 8 | "Polycat": { 9 | "FishToken": "0xC0528152e7ADba81f4017D80e3B710b7671F7dE4" 10 | }, 11 | "ERC20": { 12 | "DAI": "0x001B3B4d0F3714Ca98ba10F6042DaEbF0B1B7b6F", 13 | "amDAI": "0x639cB7b21ee2161DF9c882483C9D55c90c20Ca3e", 14 | "USDC": "0x2058A9D7613eEE744279e3856Ef0eAda5FCbaA7e", 15 | "amUSDC": "0x2271e3Fef9e15046d09E1d78a8FF038c691E9Cf9", 16 | "pmETH": "0x2f9374157Ef337620b19a720019A6FDB0593d20B" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /contracts/polycat/Farm/Operators.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; 6 | import "@openzeppelin/contracts/access/Ownable.sol"; 7 | 8 | import "./libs/IReferral.sol"; 9 | 10 | contract Operators is Ownable { 11 | mapping(address => bool) public operators; 12 | 13 | event OperatorUpdated(address indexed operator, bool indexed status); 14 | 15 | modifier onlyOperator() { 16 | require(operators[msg.sender], "Operator: caller is not the operator"); 17 | _; 18 | } 19 | 20 | // Update the status of the operator 21 | function updateOperator(address _operator, bool _status) external onlyOwner { 22 | operators[_operator] = _status; 23 | emit OperatorUpdated(_operator, _status); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IUniswapV2Router02.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | interface IUniswapV2Router02 { 5 | function swapExactTokensForTokens( 6 | uint256 amountIn, 7 | uint256 amountOutMin, 8 | address[] calldata path, 9 | address to, 10 | uint256 deadline 11 | ) external returns (uint256[] memory amounts); 12 | 13 | function swapTokensForExactTokens( 14 | uint256 amountOut, 15 | uint256 amountInMax, 16 | address[] calldata path, 17 | address to, 18 | uint256 deadline 19 | ) external returns (uint256[] memory amounts); 20 | 21 | function getAmountsOut(uint256 amountIn, address[] calldata path) 22 | external 23 | view 24 | returns (uint256[] memory amounts); 25 | 26 | function getAmountsIn(uint256 amountOut, address[] calldata path) 27 | external 28 | view 29 | returns (uint256[] memory amounts); 30 | } 31 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 4 9 | 10 | [*.sol] 11 | indent_style = space 12 | indent_size = 4 13 | 14 | [*.json] 15 | indent_style = space 16 | indent_size = 4 17 | 18 | [*.py] 19 | indent_style = space 20 | indent_size = 4 21 | 22 | [*.js] 23 | indent_style = space 24 | indent_size = 4 25 | 26 | [*.jsx] 27 | indent_style = space 28 | indent_size = 4 29 | 30 | [*.css] 31 | indent_style = space 32 | indent_size = 4 33 | 34 | [*.rb] 35 | indent_style = space 36 | indent_size = 2 37 | 38 | [*.java] 39 | indent_style = space 40 | indent_size = 4 41 | 42 | [*.php] 43 | indent_style = space 44 | tab_width = 4 45 | 46 | [*.html] 47 | indent_style = space 48 | indent_size = 2 49 | 50 | [*.md] 51 | trim_trailing_whitespace = false 52 | 53 | [{package.json,.travis.yml}] 54 | indent_style = space 55 | indent_size = 2 56 | -------------------------------------------------------------------------------- /contracts/aave-v2/flashloan/interfaces/IFlashLoanReceiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; 5 | import {ILendingPool} from '../../interfaces/ILendingPool.sol'; 6 | 7 | /** 8 | * @title IFlashLoanReceiver interface 9 | * @notice Interface for the Aave fee IFlashLoanReceiver. 10 | * @author Aave 11 | * @dev implement this interface to develop a flashloan-compatible flashLoanReceiver contract 12 | **/ 13 | interface IFlashLoanReceiver { 14 | function executeOperation( 15 | address[] calldata assets, 16 | uint256[] calldata amounts, 17 | uint256[] calldata premiums, 18 | address initiator, 19 | bytes calldata params 20 | ) external returns (bool); 21 | 22 | function ADDRESSES_PROVIDER() external view returns (ILendingPoolAddressesProvider); 23 | 24 | function LENDING_POOL() external view returns (ILendingPool); 25 | } 26 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import './BaseImmutableAdminUpgradeabilityProxy.sol'; 5 | import '../../../dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol'; 6 | 7 | /** 8 | * @title InitializableAdminUpgradeabilityProxy 9 | * @dev Extends BaseAdminUpgradeabilityProxy with an initializer function 10 | */ 11 | contract InitializableImmutableAdminUpgradeabilityProxy is 12 | BaseImmutableAdminUpgradeabilityProxy, 13 | InitializableUpgradeabilityProxy 14 | { 15 | constructor(address admin) public BaseImmutableAdminUpgradeabilityProxy(admin) {} 16 | 17 | /** 18 | * @dev Only fall back when the sender is not the admin. 19 | */ 20 | function _willFallback() internal override(BaseImmutableAdminUpgradeabilityProxy, Proxy) { 21 | BaseImmutableAdminUpgradeabilityProxy._willFallback(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/commons/yield-farming-strategy/YieldFarmingStrategyCommons.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | 6 | 7 | /** 8 | * @title YieldFarmingStrategy contract 9 | */ 10 | contract YieldFarmingStrategyCommons { 11 | 12 | ///-------------------- 13 | /// Storage types 14 | ///-------------------- 15 | 16 | mapping (address => mapping (address => UserForAaveMarket)) public userForAaveMarkets; /// Asset (ERC20) address -> User address -> UserForAave struct 17 | mapping (uint => mapping (address => UserForPolycatPool)) public userForPolycatPools; /// Pool ID -> User address -> User struct 18 | 19 | 20 | ///-------------------- 21 | /// Structs 22 | ///-------------------- 23 | 24 | struct UserForAaveMarket { 25 | uint lendingAmount; 26 | uint borrowingAmount; 27 | } 28 | 29 | struct UserForPolycatPool { 30 | uint depositingAmount; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /migrations_archive/4_deploy_YieldFarmingStrategy.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config() 2 | 3 | /// Import deployed-addresses 4 | const contractAddressList = require("./addressesList/contractAddress/contractAddress.js") 5 | const tokenAddressList = require("./addressesList/tokenAddress/tokenAddress.js") 6 | 7 | /// Artifacts 8 | const YieldFarmingStrategy = artifacts.require("YieldFarmingStrategy") 9 | const MasterChef = artifacts.require("MasterChef") 10 | const FishToken = artifacts.require("FishToken") 11 | 12 | const MASTER_CHEF = MasterChef.address 13 | //const MASTER_CHEF = contractAddressList["Polygon Mumbai"]["Polycat"]["MasterChef"] 14 | 15 | /// Deployed-addresses on Polygon Mumbai 16 | const LENDING_POOL_ADDRESSES_PROVIDER = contractAddressList["Polygon Mumbai"]["AAVE"]["LendingPoolAddressesProvider"] 17 | //const DAI_TOKEN = tokenAddressList["Polygon Mumbai"]["ERC20"]["DAI"] 18 | 19 | 20 | module.exports = async function(deployer) { 21 | await deployer.deploy(YieldFarmingStrategy, LENDING_POOL_ADDRESSES_PROVIDER, MASTER_CHEF) 22 | }; 23 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/contracts/Context.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.6.12; 3 | 4 | /* 5 | * @dev Provides information about the current execution context, including the 6 | * sender of the transaction and its data. While these are generally available 7 | * via msg.sender and msg.data, they should not be accessed in such a direct 8 | * manner, since when dealing with GSN meta-transactions the account sending and 9 | * paying for execution may not be the actual sender (as far as an application 10 | * is concerned). 11 | * 12 | * This contract is only required for intermediate, library-like contracts. 13 | */ 14 | abstract contract Context { 15 | function _msgSender() internal view virtual returns (address payable) { 16 | return msg.sender; 17 | } 18 | 19 | function _msgData() internal view virtual returns (bytes memory) { 20 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 21 | return msg.data; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/aave-v2/flashloan/base/FlashLoanReceiverBase.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; 5 | import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; 6 | import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; 7 | import {IFlashLoanReceiver} from '../interfaces/IFlashLoanReceiver.sol'; 8 | import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; 9 | import {ILendingPool} from '../../interfaces/ILendingPool.sol'; 10 | 11 | abstract contract FlashLoanReceiverBase is IFlashLoanReceiver { 12 | using SafeERC20 for IERC20; 13 | using SafeMath for uint256; 14 | 15 | ILendingPoolAddressesProvider public immutable override ADDRESSES_PROVIDER; 16 | ILendingPool public immutable override LENDING_POOL; 17 | 18 | constructor(ILendingPoolAddressesProvider provider) public { 19 | ADDRESSES_PROVIDER = provider; 20 | LENDING_POOL = ILendingPool(provider.getLendingPool()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/ICreditDelegationToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | interface ICreditDelegationToken { 5 | event BorrowAllowanceDelegated( 6 | address indexed fromUser, 7 | address indexed toUser, 8 | address asset, 9 | uint256 amount 10 | ); 11 | 12 | /** 13 | * @dev delegates borrowing power to a user on the specific debt token 14 | * @param delegatee the address receiving the delegated borrowing power 15 | * @param amount the maximum amount being delegated. Delegation will still 16 | * respect the liquidation constraints (even if delegated, a delegatee cannot 17 | * force a delegator HF to go below 1) 18 | **/ 19 | function approveDelegation(address delegatee, uint256 amount) external; 20 | 21 | /** 22 | * @dev returns the borrow allowance of the user 23 | * @param fromUser The user to giving allowance 24 | * @param toUser The user to give allowance to 25 | * @return the current allowance of toUser 26 | **/ 27 | function borrowAllowance(address fromUser, address toUser) external view returns (uint256); 28 | } 29 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IScaledBalanceToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | interface IScaledBalanceToken { 5 | /** 6 | * @dev Returns the scaled balance of the user. The scaled balance is the sum of all the 7 | * updated stored balance divided by the reserve's liquidity index at the moment of the update 8 | * @param user The user whose balance is calculated 9 | * @return The scaled balance of the user 10 | **/ 11 | function scaledBalanceOf(address user) external view returns (uint256); 12 | 13 | /** 14 | * @dev Returns the scaled balance of the user and the scaled total supply. 15 | * @param user The address of the user 16 | * @return The scaled balance of the user 17 | * @return The scaled balance and the scaled total supply 18 | **/ 19 | function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); 20 | 21 | /** 22 | * @dev Returns the scaled total supply of the variable debt token. Represents sum(debt/index) 23 | * @return The scaled total supply 24 | **/ 25 | function scaledTotalSupply() external view returns (uint256); 26 | } 27 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/ILendingPoolAddressesProviderRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | /** 5 | * @title LendingPoolAddressesProviderRegistry contract 6 | * @dev Main registry of LendingPoolAddressesProvider of multiple Aave protocol's markets 7 | * - Used for indexing purposes of Aave protocol's markets 8 | * - The id assigned to a LendingPoolAddressesProvider refers to the market it is connected with, 9 | * for example with `0` for the Aave main market and `1` for the next created 10 | * @author Aave 11 | **/ 12 | interface ILendingPoolAddressesProviderRegistry { 13 | event AddressesProviderRegistered(address indexed newAddress); 14 | event AddressesProviderUnregistered(address indexed newAddress); 15 | 16 | function getAddressesProvidersList() external view returns (address[] memory); 17 | 18 | function getAddressesProviderIdByAddress(address addressesProvider) 19 | external 20 | view 21 | returns (uint256); 22 | 23 | function registerAddressesProvider(address provider, uint256 id) external; 24 | 25 | function unregisterAddressesProvider(address provider) external; 26 | } 27 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/tokenization/DelegationAwareAToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {ILendingPool} from '../../interfaces/ILendingPool.sol'; 5 | import {IDelegationToken} from '../../interfaces/IDelegationToken.sol'; 6 | import {Errors} from '../libraries/helpers/Errors.sol'; 7 | import {AToken} from './AToken.sol'; 8 | 9 | /** 10 | * @title Aave AToken enabled to delegate voting power of the underlying asset to a different address 11 | * @dev The underlying asset needs to be compatible with the COMP delegation interface 12 | * @author Aave 13 | */ 14 | contract DelegationAwareAToken is AToken { 15 | modifier onlyPoolAdmin { 16 | require( 17 | _msgSender() == ILendingPool(_pool).getAddressesProvider().getPoolAdmin(), 18 | Errors.CALLER_NOT_POOL_ADMIN 19 | ); 20 | _; 21 | } 22 | 23 | /** 24 | * @dev Delegates voting power of the underlying asset to a `delegatee` address 25 | * @param delegatee The address that will receive the delegation 26 | **/ 27 | function delegateUnderlyingTo(address delegatee) external onlyPoolAdmin { 28 | IDelegationToken(_underlyingAsset).delegate(delegatee); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /migrations/5_deploy_YieldFarmingStrategyFactory.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config() 2 | 3 | /// Import deployed-addresses 4 | const contractAddressList = require("./addressesList/contractAddress/contractAddress.js") 5 | const tokenAddressList = require("./addressesList/tokenAddress/tokenAddress.js") 6 | 7 | /// Artifacts 8 | const YieldFarmingStrategyFactory = artifacts.require("YieldFarmingStrategyFactory") 9 | const MasterChef = artifacts.require("MasterChef") 10 | const FishToken = artifacts.require("FishToken") 11 | 12 | const FISH_TOKEN = FishToken.address 13 | const MASTER_CHEF = MasterChef.address 14 | //const MASTER_CHEF = contractAddressList["Polygon Mumbai"]["Polycat"]["MasterChef"] 15 | 16 | /// Deployed-addresses on Polygon Mumbai 17 | const LENDING_POOL_ADDRESSES_PROVIDER = contractAddressList["Polygon Mumbai"]["AAVE"]["LendingPoolAddressesProvider"] 18 | const INCENTIVES_CONTROLLER = contractAddressList["Polygon Mumbai"]["AAVE"]["IncentivesController"] 19 | //const DAI_TOKEN = tokenAddressList["Polygon Mumbai"]["ERC20"]["DAI"] 20 | 21 | 22 | module.exports = async function(deployer) { 23 | await deployer.deploy(YieldFarmingStrategyFactory, LENDING_POOL_ADDRESSES_PROVIDER, INCENTIVES_CONTROLLER, FISH_TOKEN, MASTER_CHEF) 24 | }; 25 | -------------------------------------------------------------------------------- /migrations/3_deploy_MasterChef.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config() 2 | 3 | /// Import deployed-addresses 4 | const contractAddressList = require("./addressesList/contractAddress/contractAddress.js") 5 | const tokenAddressList = require("./addressesList/tokenAddress/tokenAddress.js") 6 | 7 | const MasterChef = artifacts.require("MasterChef") 8 | const FishToken = artifacts.require("FishToken") 9 | 10 | const FISH_TOKEN = FishToken.address 11 | //const FISH_TOKEN = tokenAddressList["Polygon Mumbai"]["Polycat"]["FishToken"] 12 | 13 | const startBlock = 1 14 | const devAddress = process.env.DEV_ADDRESS 15 | const feeAddress = process.env.FEE_ADDRESS 16 | const vaultAddress = process.env.VAULT_ADDRESS 17 | 18 | 19 | module.exports = async function(deployer) { 20 | await deployer.deploy(MasterChef, FISH_TOKEN, startBlock, devAddress, feeAddress, vaultAddress) 21 | 22 | let masterChef = await MasterChef.deployed() 23 | let MASTER_CHEF = masterChef.address 24 | 25 | /// Transfer ownership of the FishToken to the MasterChef contract 26 | let fishToken = await FishToken.at(FISH_TOKEN) 27 | let txReceipt = await fishToken.transferOwnership(MASTER_CHEF) 28 | console.log("Successful to transfer ownership of the FishToken") 29 | } 30 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/libraries/helpers/Helpers.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; 5 | import {DataTypes} from '../types/DataTypes.sol'; 6 | 7 | /** 8 | * @title Helpers library 9 | * @author Aave 10 | */ 11 | library Helpers { 12 | /** 13 | * @dev Fetches the user current stable and variable debt balances 14 | * @param user The user address 15 | * @param reserve The reserve data object 16 | * @return The stable and variable debt balance 17 | **/ 18 | function getUserCurrentDebt(address user, DataTypes.ReserveData storage reserve) 19 | internal 20 | view 21 | returns (uint256, uint256) 22 | { 23 | return ( 24 | IERC20(reserve.stableDebtTokenAddress).balanceOf(user), 25 | IERC20(reserve.variableDebtTokenAddress).balanceOf(user) 26 | ); 27 | } 28 | 29 | function getUserCurrentDebtMemory(address user, DataTypes.ReserveData memory reserve) 30 | internal 31 | view 32 | returns (uint256, uint256) 33 | { 34 | return ( 35 | IERC20(reserve.stableDebtTokenAddress).balanceOf(user), 36 | IERC20(reserve.variableDebtTokenAddress).balanceOf(user) 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/upgradeability/UpgradeabilityProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import './BaseUpgradeabilityProxy.sol'; 5 | 6 | /** 7 | * @title UpgradeabilityProxy 8 | * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing 9 | * implementation and init data. 10 | */ 11 | contract UpgradeabilityProxy is BaseUpgradeabilityProxy { 12 | /** 13 | * @dev Contract constructor. 14 | * @param _logic Address of the initial implementation. 15 | * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. 16 | * It should include the signature and the parameters of the function to be called, as described in 17 | * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. 18 | * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. 19 | */ 20 | constructor(address _logic, bytes memory _data) public payable { 21 | assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)); 22 | _setImplementation(_logic); 23 | if (_data.length > 0) { 24 | (bool success, ) = _logic.delegatecall(_data); 25 | require(success); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IReserveInterestRateStrategy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | /** 5 | * @title IReserveInterestRateStrategyInterface interface 6 | * @dev Interface for the calculation of the interest rates 7 | * @author Aave 8 | */ 9 | interface IReserveInterestRateStrategy { 10 | function baseVariableBorrowRate() external view returns (uint256); 11 | 12 | function getMaxVariableBorrowRate() external view returns (uint256); 13 | 14 | function calculateInterestRates( 15 | address reserve, 16 | uint256 availableLiquidity, 17 | uint256 totalStableDebt, 18 | uint256 totalVariableDebt, 19 | uint256 averageStableBorrowRate, 20 | uint256 reserveFactor 21 | ) 22 | external 23 | view 24 | returns ( 25 | uint256, 26 | uint256, 27 | uint256 28 | ); 29 | 30 | function calculateInterestRates( 31 | address reserve, 32 | address aToken, 33 | uint256 liquidityAdded, 34 | uint256 liquidityTaken, 35 | uint256 totalStableDebt, 36 | uint256 totalVariableDebt, 37 | uint256 averageStableBorrowRate, 38 | uint256 reserveFactor 39 | ) 40 | external 41 | view 42 | returns ( 43 | uint256 liquidityRate, 44 | uint256 stableBorrowRate, 45 | uint256 variableBorrowRate 46 | ); 47 | } 48 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/lendingpool/LendingPoolStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; 5 | import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; 6 | import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; 7 | import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; 8 | import {DataTypes} from '../libraries/types/DataTypes.sol'; 9 | 10 | contract LendingPoolStorage { 11 | using ReserveLogic for DataTypes.ReserveData; 12 | using ReserveConfiguration for DataTypes.ReserveConfigurationMap; 13 | using UserConfiguration for DataTypes.UserConfigurationMap; 14 | 15 | ILendingPoolAddressesProvider internal _addressesProvider; 16 | 17 | mapping(address => DataTypes.ReserveData) internal _reserves; 18 | mapping(address => DataTypes.UserConfigurationMap) internal _usersConfig; 19 | 20 | // the list of the available reserves, structured as a mapping for gas savings reasons 21 | mapping(uint256 => address) internal _reservesList; 22 | 23 | uint256 internal _reservesCount; 24 | 25 | bool internal _paused; 26 | 27 | uint256 internal _maxStableRateBorrowSizePercent; 28 | 29 | uint256 internal _flashLoanPremiumTotal; 30 | 31 | uint256 internal _maxNumberOfReserves; 32 | } 33 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import './BaseUpgradeabilityProxy.sol'; 5 | 6 | /** 7 | * @title InitializableUpgradeabilityProxy 8 | * @dev Extends BaseUpgradeabilityProxy with an initializer for initializing 9 | * implementation and init data. 10 | */ 11 | contract InitializableUpgradeabilityProxy is BaseUpgradeabilityProxy { 12 | /** 13 | * @dev Contract initializer. 14 | * @param _logic Address of the initial implementation. 15 | * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. 16 | * It should include the signature and the parameters of the function to be called, as described in 17 | * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. 18 | * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. 19 | */ 20 | function initialize(address _logic, bytes memory _data) public payable { 21 | require(_implementation() == address(0)); 22 | assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)); 23 | _setImplementation(_logic); 24 | if (_data.length > 0) { 25 | (bool success, ) = _logic.delegatecall(_data); 26 | require(success); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/test-local/web3js-helper/web3jsHelper.js: -------------------------------------------------------------------------------- 1 | /// Using local network 2 | const Web3 = require('web3') 3 | const web3 = new Web3(new Web3.providers.WebsocketProvider('ws://localhost:8545')) 4 | 5 | function toWei(amount) { 6 | return web3.utils.toWei(`${ amount }`, 'ether') 7 | } 8 | 9 | function fromWei(amount) { 10 | return web3.utils.fromWei(`${ amount }`, 'ether') 11 | } 12 | 13 | async function getEvents(contractInstance, eventName) { 14 | const _latestBlock = await time.latestBlock() 15 | const LATEST_BLOCK = Number(String(_latestBlock)) 16 | 17 | /// [Note]: Retrieve an event log of eventName (via web3.js v1.0.0) 18 | let events = await contractInstance.getPastEvents(eventName, { 19 | filter: {}, 20 | fromBlock: LATEST_BLOCK, /// [Note]: The latest block on Mainnet 21 | //fromBlock: 0, 22 | toBlock: 'latest' 23 | }) 24 | //console.log(`\n=== [Event log]: ${ eventName } ===`, events[0].returnValues) 25 | return events[0].returnValues 26 | } 27 | 28 | async function getCurrentBlock() { 29 | const currentBlock = await web3.eth.getBlockNumber() 30 | return currentBlock 31 | } 32 | 33 | async function getCurrentTimestamp() { 34 | const currentBlock = await web3.eth.getBlockNumber() 35 | const currentTimestamp = await web3.eth.getBlock(currentBlock).timestamp 36 | 37 | return currentTimestamp 38 | } 39 | 40 | /// Export methods 41 | module.exports = { toWei, fromWei, getEvents, getCurrentBlock, getCurrentTimestamp } 42 | -------------------------------------------------------------------------------- /scripts/web3js-helper/web3jsHelper.js: -------------------------------------------------------------------------------- 1 | /// Web3 instance 2 | const Web3 = require('web3') 3 | const provider = new Web3.providers.HttpProvider(`https://polygon-mumbai.infura.io/v3/${ process.env.INFURA_KEY }`) 4 | const web3 = new Web3(provider) 5 | 6 | function toWei(amount) { 7 | return web3.utils.toWei(`${ amount }`, 'ether') 8 | } 9 | 10 | function fromWei(amount) { 11 | return web3.utils.fromWei(`${ amount }`, 'ether') 12 | } 13 | 14 | async function getEvents(contractInstance, eventName) { 15 | const _latestBlock = await getCurrentBlock() 16 | const LATEST_BLOCK = Number(String(_latestBlock)) 17 | 18 | /// [Note]: Retrieve an event log of eventName (via web3.js v1.0.0) 19 | let events = await contractInstance.getPastEvents(eventName, { 20 | filter: {}, 21 | fromBlock: LATEST_BLOCK - 10, /// [Note]: Check emittied-events from 10 block ago (The latest block - 10) 22 | //fromBlock: 0, 23 | toBlock: 'latest' 24 | }) 25 | //console.log(`\n=== [Event log]: ${ eventName } ===`, events[0].returnValues) 26 | return events[0].returnValues 27 | } 28 | 29 | async function getCurrentBlock() { 30 | const currentBlock = await web3.eth.getBlockNumber() 31 | return currentBlock 32 | } 33 | 34 | async function getCurrentTimestamp() { 35 | const currentBlock = await web3.eth.getBlockNumber() 36 | const currentTimestamp = await web3.eth.getBlock(currentBlock).timestamp 37 | 38 | return currentTimestamp 39 | } 40 | 41 | /// Export methods 42 | module.exports = { toWei, fromWei, getEvents, getCurrentBlock, getCurrentTimestamp } 43 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/upgradeability/AdminUpgradeabilityProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import './BaseAdminUpgradeabilityProxy.sol'; 5 | 6 | /** 7 | * @title AdminUpgradeabilityProxy 8 | * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for 9 | * initializing the implementation, admin, and init data. 10 | */ 11 | contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy { 12 | /** 13 | * Contract constructor. 14 | * @param _logic address of the initial implementation. 15 | * @param _admin Address of the proxy administrator. 16 | * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. 17 | * It should include the signature and the parameters of the function to be called, as described in 18 | * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. 19 | * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. 20 | */ 21 | constructor( 22 | address _logic, 23 | address _admin, 24 | bytes memory _data 25 | ) public payable UpgradeabilityProxy(_logic, _data) { 26 | assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)); 27 | _setAdmin(_admin); 28 | } 29 | 30 | /** 31 | * @dev Only fall back when the sender is not the admin. 32 | */ 33 | function _willFallback() internal override(BaseAdminUpgradeabilityProxy, Proxy) { 34 | BaseAdminUpgradeabilityProxy._willFallback(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "forceDAO-yield-farming-strategy-on-polygon", 3 | "version": "1.0.0", 4 | "description": "", 5 | "directories": { 6 | "test": "test" 7 | }, 8 | "scripts": { 9 | "script:YieldFarmingStrategy": "truffle exec ./scripts/polygon-mumbai/YieldFarmingStrategy.script.js --network polygon_mumbai", 10 | "test": "truffle test ./test/test-local/* --network local", 11 | "test:YieldFarmingStrategy": "truffle test ./test/test-local/YieldFarmingStrategy.test.js --network local", 12 | "test:MasterChef": "truffle test ./test/test-local/polycat/MasterChef.test.js --network local", 13 | "test:Sai": "truffle test ./test/test-local/truffle-mint-dai/sai.js --network local", 14 | "test:Dai": "truffle test ./test/test-local/truffle-mint-dai/dai.js --network local", 15 | "test:Usdc": "truffle test ./test/test-local/truffle-mint-dai/usdc.js --network local", 16 | "test:Usdt": "truffle test ./test/test-local/truffle-mint-dai/usdt.js --network local", 17 | "compile:local": "truffle compile --reset --network local", 18 | "migrate:local": "truffle migrate --reset --network local", 19 | "compile:polygon_mumbai": "truffle compile --reset --network polygon_mumbai", 20 | "migrate:polygon_mumbai": "truffle migrate --reset --network polygon_mumbai" 21 | }, 22 | "author": "masaun", 23 | "license": "MIT", 24 | "dependencies": { 25 | "@openzeppelin/contracts": "^3.4.1", 26 | "@openzeppelin/test-helpers": "^0.5.10", 27 | "@truffle/hdwallet-provider": "^1.3.0", 28 | "dotenv": "^8.2.0", 29 | "eth-block-tracker": "^4.4.3" 30 | }, 31 | "devDependencies": {} 32 | } 33 | -------------------------------------------------------------------------------- /truffle-config.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | 3 | const HDWalletProvider = require('@truffle/hdwallet-provider'); // @notice - Should use new module. 4 | const mnemonic = process.env.MNEMONIC; 5 | 6 | module.exports = { 7 | networks: { 8 | polygon_mumbai: { /// Mumbai testnet of Matic 9 | provider: () => new HDWalletProvider(mnemonic, "https://polygon-mumbai.infura.io/v3/" + process.env.INFURA_KEY), 10 | network_id: 80001, 11 | confirmations: 2, 12 | timeoutBlocks: 200, 13 | skipDryRun: true 14 | }, 15 | goerli: { 16 | provider: () => new HDWalletProvider(mnemonic, "https://goerli.infura.io/v3/" + process.env.INFURA_KEY), 17 | network_id: 5, 18 | gas: 7500000, 19 | gasPrice: 5000000000, // 5 gwei, 20 | skipDryRun: true, // Skip dry run before migrations? (default: false for public nets) 21 | //from: process.env.DEPLOYER_ADDRESS 22 | }, 23 | // main ethereum network(mainnet) 24 | live: { 25 | provider: () => new HDWalletProvider(mnemonic, "https://mainnet.infura.io/v3/" + process.env.INFURA_KEY), 26 | network_id: 1, 27 | gas: 5500000, 28 | gasPrice: 2000000000 // 2 gwei 29 | }, 30 | local: { 31 | host: '127.0.0.1', 32 | port: 8545, 33 | network_id: '*', 34 | skipDryRun: true, 35 | gasPrice: 5000000000 36 | } 37 | }, 38 | 39 | compilers: { 40 | solc: { 41 | version: "pragma", /// For compiling multiple solc-versions 42 | settings: { 43 | optimizer: { 44 | enabled: true, 45 | runs: 200 46 | } 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /test/test-local/truffle-mint-dai/dai.js: -------------------------------------------------------------------------------- 1 | const { BN, ether, balance } = require('@openzeppelin/test-helpers'); 2 | const { expect } = require('chai'); 3 | const { asyncForEach } = require('./utils'); 4 | 5 | // ABI 6 | const daiABI = require('./abi/dai'); 7 | 8 | // userAddress must be unlocked using --unlock ADDRESS 9 | const userAddress = '0x9eb7f2591ed42dee9315b6e2aaf21ba85ea69f8c'; 10 | const daiAddress = '0x6B175474E89094C44Da98b954EedeAC495271d0F'; 11 | const daiContract = new web3.eth.Contract(daiABI, daiAddress); 12 | 13 | contract('Truffle Mint DAI', async accounts => { 14 | it('should send ether to the DAI address', async () => { 15 | //console.log('=== accounts ===', accounts) 16 | 17 | // Send 0.1 eth to userAddress to have gas to send an ERC20 tx. 18 | await web3.eth.sendTransaction({ 19 | from: accounts[0], 20 | to: userAddress, 21 | value: ether('0.1') 22 | }); 23 | const ethBalance = await balance.current(userAddress); 24 | expect(new BN(ethBalance)).to.be.bignumber.least(new BN(ether('0.1'))); 25 | }); 26 | 27 | it('should mint DAI for our first 5 generated accounts', async () => { 28 | // Get 100 DAI for first 5 accounts 29 | await asyncForEach(accounts.slice(0, 5), async account => { 30 | // daiAddress is passed to ganache-cli with flag `--unlock` 31 | // so we can use the `transfer` method 32 | await daiContract.methods 33 | .transfer(account, ether('100').toString()) 34 | .send({ from: userAddress, gasLimit: 800000 }); 35 | const daiBalance = await daiContract.methods.balanceOf(account).call(); 36 | expect(new BN(daiBalance)).to.be.bignumber.least(ether('100')); 37 | }); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/libraries/types/DataTypes.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | library DataTypes { 5 | // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. 6 | struct ReserveData { 7 | //stores the reserve configuration 8 | ReserveConfigurationMap configuration; 9 | //the liquidity index. Expressed in ray 10 | uint128 liquidityIndex; 11 | //variable borrow index. Expressed in ray 12 | uint128 variableBorrowIndex; 13 | //the current supply rate. Expressed in ray 14 | uint128 currentLiquidityRate; 15 | //the current variable borrow rate. Expressed in ray 16 | uint128 currentVariableBorrowRate; 17 | //the current stable borrow rate. Expressed in ray 18 | uint128 currentStableBorrowRate; 19 | uint40 lastUpdateTimestamp; 20 | //tokens addresses 21 | address aTokenAddress; 22 | address stableDebtTokenAddress; 23 | address variableDebtTokenAddress; 24 | //address of the interest rate strategy 25 | address interestRateStrategyAddress; 26 | //the id of the reserve. Represents the position in the list of the active reserves 27 | uint8 id; 28 | } 29 | 30 | struct ReserveConfigurationMap { 31 | //bit 0-15: LTV 32 | //bit 16-31: Liq. threshold 33 | //bit 32-47: Liq. bonus 34 | //bit 48-55: Decimals 35 | //bit 56: Reserve is active 36 | //bit 57: reserve is frozen 37 | //bit 58: borrowing is enabled 38 | //bit 59: stable rate borrowing enabled 39 | //bit 60-63: reserved 40 | //bit 64-79: reserve factor 41 | uint256 data; 42 | } 43 | 44 | struct UserConfigurationMap { 45 | uint256 data; 46 | } 47 | 48 | enum InterestRateMode {NONE, STABLE, VARIABLE} 49 | } 50 | -------------------------------------------------------------------------------- /contracts/polycat/Farm/Referral.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; 6 | import "@openzeppelin/contracts/access/Ownable.sol"; 7 | 8 | import "./libs/IReferral.sol"; 9 | 10 | contract Referral is IReferral, Ownable { 11 | using SafeERC20 for IERC20; 12 | 13 | mapping(address => bool) public operators; 14 | mapping(address => address) public referrers; // user address => referrer address 15 | mapping(address => uint256) public referralsCount; // referrer address => referrals count 16 | 17 | event ReferralRecorded(address indexed user, address indexed referrer); 18 | event OperatorUpdated(address indexed operator, bool indexed status); 19 | 20 | modifier onlyOperator { 21 | require(operators[msg.sender], "Operator: caller is not the operator"); 22 | _; 23 | } 24 | 25 | function recordReferral(address _user, address _referrer) public override onlyOperator { 26 | if (_user != address(0) 27 | && _referrer != address(0) 28 | && _user != _referrer 29 | && referrers[_user] == address(0) 30 | ) { 31 | referrers[_user] = _referrer; 32 | referralsCount[_referrer] += 1; 33 | emit ReferralRecorded(_user, _referrer); 34 | } 35 | } 36 | 37 | // Get the referrer address that referred the user 38 | function getReferrer(address _user) public override view returns (address) { 39 | return referrers[_user]; 40 | } 41 | 42 | // Update the status of the operator 43 | function updateOperator(address _operator, bool _status) external onlyOwner { 44 | operators[_operator] = _status; 45 | emit OperatorUpdated(_operator, _status); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/upgradeability/InitializableAdminUpgradeabilityProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import './BaseAdminUpgradeabilityProxy.sol'; 5 | import './InitializableUpgradeabilityProxy.sol'; 6 | 7 | /** 8 | * @title InitializableAdminUpgradeabilityProxy 9 | * @dev Extends from BaseAdminUpgradeabilityProxy with an initializer for 10 | * initializing the implementation, admin, and init data. 11 | */ 12 | contract InitializableAdminUpgradeabilityProxy is 13 | BaseAdminUpgradeabilityProxy, 14 | InitializableUpgradeabilityProxy 15 | { 16 | /** 17 | * Contract initializer. 18 | * @param logic address of the initial implementation. 19 | * @param admin Address of the proxy administrator. 20 | * @param data Data to send as msg.data to the implementation to initialize the proxied contract. 21 | * It should include the signature and the parameters of the function to be called, as described in 22 | * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. 23 | * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. 24 | */ 25 | function initialize( 26 | address logic, 27 | address admin, 28 | bytes memory data 29 | ) public payable { 30 | require(_implementation() == address(0)); 31 | InitializableUpgradeabilityProxy.initialize(logic, data); 32 | assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)); 33 | _setAdmin(admin); 34 | } 35 | 36 | /** 37 | * @dev Only fall back when the sender is not the admin. 38 | */ 39 | function _willFallback() internal override(BaseAdminUpgradeabilityProxy, Proxy) { 40 | BaseAdminUpgradeabilityProxy._willFallback(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/libraries/math/PercentageMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {Errors} from '../helpers/Errors.sol'; 5 | 6 | /** 7 | * @title PercentageMath library 8 | * @author Aave 9 | * @notice Provides functions to perform percentage calculations 10 | * @dev Percentages are defined by default with 2 decimals of precision (100.00). The precision is indicated by PERCENTAGE_FACTOR 11 | * @dev Operations are rounded half up 12 | **/ 13 | 14 | library PercentageMath { 15 | uint256 constant PERCENTAGE_FACTOR = 1e4; //percentage plus two decimals 16 | uint256 constant HALF_PERCENT = PERCENTAGE_FACTOR / 2; 17 | 18 | /** 19 | * @dev Executes a percentage multiplication 20 | * @param value The value of which the percentage needs to be calculated 21 | * @param percentage The percentage of the value to be calculated 22 | * @return The percentage of value 23 | **/ 24 | function percentMul(uint256 value, uint256 percentage) internal pure returns (uint256) { 25 | if (value == 0 || percentage == 0) { 26 | return 0; 27 | } 28 | 29 | require( 30 | value <= (type(uint256).max - HALF_PERCENT) / percentage, 31 | Errors.MATH_MULTIPLICATION_OVERFLOW 32 | ); 33 | 34 | return (value * percentage + HALF_PERCENT) / PERCENTAGE_FACTOR; 35 | } 36 | 37 | /** 38 | * @dev Executes a percentage division 39 | * @param value The value of which the percentage needs to be calculated 40 | * @param percentage The percentage of the value to be calculated 41 | * @return The value divided the percentage 42 | **/ 43 | function percentDiv(uint256 value, uint256 percentage) internal pure returns (uint256) { 44 | require(percentage != 0, Errors.MATH_DIVISION_BY_ZERO); 45 | uint256 halfPercentage = percentage / 2; 46 | 47 | require( 48 | value <= (type(uint256).max - halfPercentage) / PERCENTAGE_FACTOR, 49 | Errors.MATH_MULTIPLICATION_OVERFLOW 50 | ); 51 | 52 | return (value * PERCENTAGE_FACTOR + halfPercentage) / percentage; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /test/test-local/truffle-mint-dai/sai.js: -------------------------------------------------------------------------------- 1 | const { BN, ether, balance } = require('@openzeppelin/test-helpers'); 2 | const { expect } = require('chai'); 3 | const { asyncForEach } = require('./utils'); 4 | 5 | // Artifacts 6 | const ForceSend = artifacts.require('ForceSend'); 7 | 8 | // ABI 9 | const erc20ABI = require('./abi/erc20'); 10 | 11 | // saiAddress must be unlocked using --unlock 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359 12 | const saiAddress = '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359'; // SAI address on Mainnet 13 | const saiContract = new web3.eth.Contract(erc20ABI, saiAddress); 14 | 15 | // Utils 16 | const getSaiBalance = async account => { 17 | return saiContract.methods.balanceOf(account).call(); 18 | }; 19 | 20 | contract('Truffle Mint SAI', async accounts => { 21 | it('should send ether to the SAI contract', async () => { 22 | // Send 1 eth to saiAddress to have gas to mint. 23 | // Uses ForceSend contract, otherwise just sending 24 | // a normal tx will revert. 25 | const forceSend = await ForceSend.new(); 26 | await forceSend.go(saiAddress, { value: ether('1') }); 27 | const ethBalance = await balance.current(saiAddress); 28 | expect(new BN(ethBalance)).to.be.bignumber.least(new BN(ether('1'))); 29 | }); 30 | 31 | it('should mint 100 SAI for our first 5 generated accounts', async () => { 32 | // Get 100 SAI for first 5 accounts 33 | await asyncForEach(accounts.slice(0, 5), async account => { 34 | // saiAddress is passed to ganache-cli with flag `--unlock` 35 | // so we can use the `mint` method. 36 | await saiContract.methods 37 | .mint(account, ether('100').toString()) 38 | .send({ from: saiAddress }); 39 | const saiBalance = await getSaiBalance(account); 40 | expect(new BN(saiBalance)).to.be.bignumber.least(ether('100')); 41 | }); 42 | }); 43 | 44 | it('SAI balance', async () => { 45 | const SaiBalance = await getSaiBalance(accounts[0]) 46 | console.log('=== SAI balance of accounts[0] ===', web3.utils.fromWei(SaiBalance, 'ether')) 47 | }) 48 | }); 49 | -------------------------------------------------------------------------------- /test/test-local/truffle-mint-dai/usdt.js: -------------------------------------------------------------------------------- 1 | const { BN, ether, balance } = require('@openzeppelin/test-helpers'); 2 | const { expect } = require('chai'); 3 | const { asyncForEach } = require('./utils'); 4 | 5 | // Artifacts 6 | const ForceSend = artifacts.require('ForceSend'); 7 | 8 | // ABI 9 | const erc20ABI = require('./abi/erc20'); 10 | 11 | // usdtAddress must be unlocked using --unlock 0xdAC17F958D2ee523a2206206994597C13D831ec7 12 | const usdtAddress = '0xdAC17F958D2ee523a2206206994597C13D831ec7'; // USDT address on Mainnet 13 | const usdtContract = new web3.eth.Contract(erc20ABI, usdtAddress); 14 | 15 | // Utils 16 | const getUsdtBalance = async account => { 17 | return usdtContract.methods.balanceOf(account).call(); 18 | }; 19 | 20 | contract('Truffle Mint USDT', async accounts => { 21 | it('should send ether to the USDT contract', async () => { 22 | // Send 1 eth to usdtAddress to have gas to mint. 23 | // Uses ForceSend contract, otherwise just sending 24 | // a normal tx will revert. 25 | const forceSend = await ForceSend.new(); 26 | await forceSend.go(usdtAddress, { value: ether('1') }); 27 | const ethBalance = await balance.current(usdtAddress); 28 | expect(new BN(ethBalance)).to.be.bignumber.least(new BN(ether('1'))); 29 | }); 30 | 31 | it('should mint 100 USDT for our first 5 generated accounts', async () => { 32 | // Get 100 USDT for first 5 accounts 33 | await asyncForEach(accounts.slice(0, 5), async account => { 34 | // usdtAddress is passed to ganache-cli with flag `--unlock` 35 | // so we can use the `mint` method. 36 | await usdtContract.methods 37 | .mint(account, ether('100').toString()) 38 | .send({ from: usdtAddress }); 39 | const usdtBalance = await getUSDTBalance(account); 40 | expect(new BN(usdtBalance)).to.be.bignumber.least(ether('100')); 41 | }); 42 | }); 43 | 44 | it('USDT balance', async () => { 45 | const UsdtBalance = await getUsdtBalance(accounts[0]) 46 | console.log('=== USDT balance of accounts[0] ===', web3.utils.fromWei(UsdtBalance, 'ether')) 47 | }) 48 | }); 49 | -------------------------------------------------------------------------------- /test/test-local/truffle-mint-dai/usdc.js: -------------------------------------------------------------------------------- 1 | const { BN, ether, balance } = require('@openzeppelin/test-helpers'); 2 | const { expect } = require('chai'); 3 | const { asyncForEach } = require('./utils'); 4 | 5 | // Artifacts 6 | const ForceSend = artifacts.require('ForceSend'); 7 | 8 | // ABI 9 | const erc20ABI = require('./abi/usdc-abi'); 10 | 11 | // usdcAddress must be unlocked using --unlock 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 12 | const usdcAddress = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; // USDC address on Mainnet 13 | const usdcContract = new web3.eth.Contract(erc20ABI, usdcAddress); 14 | 15 | // Utils 16 | const getUsdcBalance = async account => { 17 | return usdcContract.methods.balanceOf(account).call(); 18 | }; 19 | 20 | contract('Truffle Mint USDC', async accounts => { 21 | it('should send ether to the USDC contract', async () => { 22 | // Send 1 eth to usdcAddress to have gas to mint. 23 | // Uses ForceSend contract, otherwise just sending 24 | // a normal tx will revert. 25 | const forceSend = await ForceSend.new(); 26 | await forceSend.go(usdcAddress, { value: ether('1') }); 27 | const ethBalance = await balance.current(usdcAddress); 28 | expect(new BN(ethBalance)).to.be.bignumber.least(new BN(ether('1'))); 29 | }); 30 | 31 | it('should mint 100 USDC for our first 5 generated accounts', async () => { 32 | // Get 100 USDC for first 5 accounts 33 | await asyncForEach(accounts.slice(0, 5), async account => { 34 | // usdcAddress is passed to ganache-cli with flag `--unlock` 35 | // so we can use the `mint` method. 36 | await usdcContract.methods 37 | .mint(account, ether('100').toString()) 38 | .send({ from: usdcAddress }); 39 | const usdcBalance = await getUsdcBalance(account); 40 | expect(new BN(usdcBalance)).to.be.bignumber.least(ether('100')); 41 | }); 42 | }); 43 | 44 | it('USDC balance', async () => { 45 | const UsdcBalance = await getUsdcBalance(accounts[0]) 46 | console.log('=== USDC balance of accounts[0] ===', web3.utils.fromWei(UsdcBalance, 'ether')) 47 | }) 48 | }); 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | ganache 3 | contractAddresses 4 | package-lock.json 5 | .secret 6 | output 7 | 8 | /node_modules 9 | 10 | 11 | 12 | #------------------------------------------ 13 | 14 | 15 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 16 | 17 | # Log of ethereum-bridge (for provable-things) 18 | bridge.log 19 | 20 | # lol macs 21 | .DS_Store/ 22 | 23 | # dependencies 24 | /node_modules 25 | /.pnp 26 | .pnp.js 27 | 28 | # testing 29 | /coverage 30 | 31 | # production 32 | /build 33 | 34 | # misc 35 | .DS_Store 36 | .env.local 37 | .env.development.local 38 | .env.test.local 39 | .env.production.local 40 | 41 | npm-debug.log* 42 | yarn-debug.log* 43 | yarn-error.log* 44 | 45 | 46 | # Logs 47 | .DS_Store 48 | logs 49 | *.log 50 | npm-debug.log* 51 | yarn-debug.log* 52 | yarn-error.log* 53 | 54 | # Runtime data 55 | pids 56 | *.pid 57 | *.seed 58 | *.pid.lock 59 | 60 | # Directory for instrumented libs generated by jscoverage/JSCover 61 | lib-cov 62 | 63 | # Coverage directory used by tools like istanbul 64 | coverage 65 | 66 | # nyc test coverage 67 | .nyc_output 68 | 69 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 70 | .grunt 71 | 72 | # Bower dependency directory (https://bower.io/) 73 | bower_components 74 | 75 | # node-waf configuration 76 | .lock-wscript 77 | 78 | # Compiled binary addons (https://nodejs.org/api/addons.html) 79 | build/Release 80 | 81 | # Dependency directories 82 | node_modules/ 83 | jspm_packages/ 84 | 85 | # TypeScript v1 declaration files 86 | typings/ 87 | 88 | # Optional npm cache directory 89 | .npm 90 | 91 | # Optional eslint cache 92 | .eslintcache 93 | 94 | # Optional REPL history 95 | .node_repl_history 96 | 97 | # Output of 'npm pack' 98 | *.tgz 99 | 100 | # Yarn Integrity file 101 | .yarn-integrity 102 | 103 | # dotenv environment variables file 104 | .env 105 | 106 | # next.js build output 107 | .next 108 | 109 | # zos sessions 110 | zos.dev-* 111 | 112 | # contracts build 113 | build 114 | 115 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IInitializableDebtToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {ILendingPool} from './ILendingPool.sol'; 5 | import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; 6 | 7 | /** 8 | * @title IInitializableDebtToken 9 | * @notice Interface for the initialize function common between debt tokens 10 | * @author Aave 11 | **/ 12 | interface IInitializableDebtToken { 13 | /** 14 | * @dev Emitted when a debt token is initialized 15 | * @param underlyingAsset The address of the underlying asset 16 | * @param pool The address of the associated lending pool 17 | * @param incentivesController The address of the incentives controller for this aToken 18 | * @param debtTokenDecimals the decimals of the debt token 19 | * @param debtTokenName the name of the debt token 20 | * @param debtTokenSymbol the symbol of the debt token 21 | * @param params A set of encoded parameters for additional initialization 22 | **/ 23 | event Initialized( 24 | address indexed underlyingAsset, 25 | address indexed pool, 26 | address incentivesController, 27 | uint8 debtTokenDecimals, 28 | string debtTokenName, 29 | string debtTokenSymbol, 30 | bytes params 31 | ); 32 | 33 | /** 34 | * @dev Initializes the debt token. 35 | * @param pool The address of the lending pool where this aToken will be used 36 | * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH) 37 | * @param incentivesController The smart contract managing potential incentives distribution 38 | * @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's 39 | * @param debtTokenName The name of the token 40 | * @param debtTokenSymbol The symbol of the token 41 | */ 42 | function initialize( 43 | ILendingPool pool, 44 | address underlyingAsset, 45 | IAaveIncentivesController incentivesController, 46 | uint8 debtTokenDecimals, 47 | string memory debtTokenName, 48 | string memory debtTokenSymbol, 49 | bytes calldata params 50 | ) external; 51 | } 52 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IInitializableAToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {ILendingPool} from './ILendingPool.sol'; 5 | import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; 6 | 7 | /** 8 | * @title IInitializableAToken 9 | * @notice Interface for the initialize function on AToken 10 | * @author Aave 11 | **/ 12 | interface IInitializableAToken { 13 | /** 14 | * @dev Emitted when an aToken is initialized 15 | * @param underlyingAsset The address of the underlying asset 16 | * @param pool The address of the associated lending pool 17 | * @param treasury The address of the treasury 18 | * @param incentivesController The address of the incentives controller for this aToken 19 | * @param aTokenDecimals the decimals of the underlying 20 | * @param aTokenName the name of the aToken 21 | * @param aTokenSymbol the symbol of the aToken 22 | * @param params A set of encoded parameters for additional initialization 23 | **/ 24 | event Initialized( 25 | address indexed underlyingAsset, 26 | address indexed pool, 27 | address treasury, 28 | address incentivesController, 29 | uint8 aTokenDecimals, 30 | string aTokenName, 31 | string aTokenSymbol, 32 | bytes params 33 | ); 34 | 35 | /** 36 | * @dev Initializes the aToken 37 | * @param pool The address of the lending pool where this aToken will be used 38 | * @param treasury The address of the Aave treasury, receiving the fees on this aToken 39 | * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH) 40 | * @param incentivesController The smart contract managing potential incentives distribution 41 | * @param aTokenDecimals The decimals of the aToken, same as the underlying asset's 42 | * @param aTokenName The name of the aToken 43 | * @param aTokenSymbol The symbol of the aToken 44 | */ 45 | function initialize( 46 | ILendingPool pool, 47 | address treasury, 48 | address underlyingAsset, 49 | IAaveIncentivesController incentivesController, 50 | uint8 aTokenDecimals, 51 | string calldata aTokenName, 52 | string calldata aTokenSymbol, 53 | bytes calldata params 54 | ) external; 55 | } 56 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import './Proxy.sol'; 5 | import '../contracts/Address.sol'; 6 | 7 | /** 8 | * @title BaseUpgradeabilityProxy 9 | * @dev This contract implements a proxy that allows to change the 10 | * implementation address to which it will delegate. 11 | * Such a change is called an implementation upgrade. 12 | */ 13 | contract BaseUpgradeabilityProxy is Proxy { 14 | /** 15 | * @dev Emitted when the implementation is upgraded. 16 | * @param implementation Address of the new implementation. 17 | */ 18 | event Upgraded(address indexed implementation); 19 | 20 | /** 21 | * @dev Storage slot with the address of the current implementation. 22 | * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is 23 | * validated in the constructor. 24 | */ 25 | bytes32 internal constant IMPLEMENTATION_SLOT = 26 | 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; 27 | 28 | /** 29 | * @dev Returns the current implementation. 30 | * @return impl Address of the current implementation 31 | */ 32 | function _implementation() internal view override returns (address impl) { 33 | bytes32 slot = IMPLEMENTATION_SLOT; 34 | //solium-disable-next-line 35 | assembly { 36 | impl := sload(slot) 37 | } 38 | } 39 | 40 | /** 41 | * @dev Upgrades the proxy to a new implementation. 42 | * @param newImplementation Address of the new implementation. 43 | */ 44 | function _upgradeTo(address newImplementation) internal { 45 | _setImplementation(newImplementation); 46 | emit Upgraded(newImplementation); 47 | } 48 | 49 | /** 50 | * @dev Sets the implementation address of the proxy. 51 | * @param newImplementation Address of the new implementation. 52 | */ 53 | function _setImplementation(address newImplementation) internal { 54 | require( 55 | Address.isContract(newImplementation), 56 | 'Cannot set a proxy implementation to a non-contract address' 57 | ); 58 | 59 | bytes32 slot = IMPLEMENTATION_SLOT; 60 | 61 | //solium-disable-next-line 62 | assembly { 63 | sstore(slot, newImplementation) 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/contracts/SafeERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import {IERC20} from './IERC20.sol'; 6 | import {SafeMath} from './SafeMath.sol'; 7 | import {Address} from './Address.sol'; 8 | 9 | /** 10 | * @title SafeERC20 11 | * @dev Wrappers around ERC20 operations that throw on failure (when the token 12 | * contract returns false). Tokens that return no value (and instead revert or 13 | * throw on failure) are also supported, non-reverting calls are assumed to be 14 | * successful. 15 | * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, 16 | * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. 17 | */ 18 | library SafeERC20 { 19 | using SafeMath for uint256; 20 | using Address for address; 21 | 22 | function safeTransfer( 23 | IERC20 token, 24 | address to, 25 | uint256 value 26 | ) internal { 27 | callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 28 | } 29 | 30 | function safeTransferFrom( 31 | IERC20 token, 32 | address from, 33 | address to, 34 | uint256 value 35 | ) internal { 36 | callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 37 | } 38 | 39 | function safeApprove( 40 | IERC20 token, 41 | address spender, 42 | uint256 value 43 | ) internal { 44 | require( 45 | (value == 0) || (token.allowance(address(this), spender) == 0), 46 | 'SafeERC20: approve from non-zero to non-zero allowance' 47 | ); 48 | callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 49 | } 50 | 51 | function callOptionalReturn(IERC20 token, bytes memory data) private { 52 | require(address(token).isContract(), 'SafeERC20: call to non-contract'); 53 | 54 | // solhint-disable-next-line avoid-low-level-calls 55 | (bool success, bytes memory returndata) = address(token).call(data); 56 | require(success, 'SafeERC20: low-level call failed'); 57 | 58 | if (returndata.length > 0) { 59 | // Return data is optional 60 | // solhint-disable-next-line max-line-length 61 | require(abi.decode(returndata, (bool)), 'SafeERC20: ERC20 operation did not succeed'); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IVariableDebtToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {IScaledBalanceToken} from './IScaledBalanceToken.sol'; 5 | import {IInitializableDebtToken} from './IInitializableDebtToken.sol'; 6 | import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; 7 | 8 | /** 9 | * @title IVariableDebtToken 10 | * @author Aave 11 | * @notice Defines the basic interface for a variable debt token. 12 | **/ 13 | interface IVariableDebtToken is IScaledBalanceToken, IInitializableDebtToken { 14 | /** 15 | * @dev Emitted after the mint action 16 | * @param from The address performing the mint 17 | * @param onBehalfOf The address of the user on which behalf minting has been performed 18 | * @param value The amount to be minted 19 | * @param index The last index of the reserve 20 | **/ 21 | event Mint(address indexed from, address indexed onBehalfOf, uint256 value, uint256 index); 22 | 23 | /** 24 | * @dev Mints debt token to the `onBehalfOf` address 25 | * @param user The address receiving the borrowed underlying, being the delegatee in case 26 | * of credit delegate, or same as `onBehalfOf` otherwise 27 | * @param onBehalfOf The address receiving the debt tokens 28 | * @param amount The amount of debt being minted 29 | * @param index The variable debt index of the reserve 30 | * @return `true` if the the previous balance of the user is 0 31 | **/ 32 | function mint( 33 | address user, 34 | address onBehalfOf, 35 | uint256 amount, 36 | uint256 index 37 | ) external returns (bool); 38 | 39 | /** 40 | * @dev Emitted when variable debt is burnt 41 | * @param user The user which debt has been burned 42 | * @param amount The amount of debt being burned 43 | * @param index The index of the user 44 | **/ 45 | event Burn(address indexed user, uint256 amount, uint256 index); 46 | 47 | /** 48 | * @dev Burns user variable debt 49 | * @param user The user which debt is burnt 50 | * @param index The variable debt index of the reserve 51 | **/ 52 | function burn( 53 | address user, 54 | uint256 amount, 55 | uint256 index 56 | ) external; 57 | 58 | /** 59 | * @dev Returns the address of the incentives controller contract 60 | **/ 61 | function getIncentivesController() external view returns (IAaveIncentivesController); 62 | } 63 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/upgradeability/Initializable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity >=0.4.24 <0.7.0; 3 | 4 | /** 5 | * @title Initializable 6 | * 7 | * @dev Helper contract to support initializer functions. To use it, replace 8 | * the constructor with a function that has the `initializer` modifier. 9 | * WARNING: Unlike constructors, initializer functions must be manually 10 | * invoked. This applies both to deploying an Initializable contract, as well 11 | * as extending an Initializable contract via inheritance. 12 | * WARNING: When used with inheritance, manual care must be taken to not invoke 13 | * a parent initializer twice, or ensure that all initializers are idempotent, 14 | * because this is not dealt with automatically as with constructors. 15 | */ 16 | contract Initializable { 17 | /** 18 | * @dev Indicates that the contract has been initialized. 19 | */ 20 | bool private initialized; 21 | 22 | /** 23 | * @dev Indicates that the contract is in the process of being initialized. 24 | */ 25 | bool private initializing; 26 | 27 | /** 28 | * @dev Modifier to use in the initializer function of a contract. 29 | */ 30 | modifier initializer() { 31 | require( 32 | initializing || isConstructor() || !initialized, 33 | 'Contract instance has already been initialized' 34 | ); 35 | 36 | bool isTopLevelCall = !initializing; 37 | if (isTopLevelCall) { 38 | initializing = true; 39 | initialized = true; 40 | } 41 | 42 | _; 43 | 44 | if (isTopLevelCall) { 45 | initializing = false; 46 | } 47 | } 48 | 49 | /// @dev Returns true if and only if the function is running in the constructor 50 | function isConstructor() private view returns (bool) { 51 | // extcodesize checks the size of the code stored in an address, and 52 | // address returns the current address. Since the code is still not 53 | // deployed when running a constructor, any checks on its code size will 54 | // yield zero, making it an effective way to detect if a contract is 55 | // under construction or not. 56 | uint256 cs; 57 | //solium-disable-next-line 58 | assembly { 59 | cs := extcodesize(address()) 60 | } 61 | return cs == 0; 62 | } 63 | 64 | // Reserved storage space to allow for layout changes in the future. 65 | uint256[50] private ______gap; 66 | } 67 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/contracts/Ownable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.0; 4 | 5 | import './Context.sol'; 6 | 7 | /** 8 | * @dev Contract module which provides a basic access control mechanism, where 9 | * there is an account (an owner) that can be granted exclusive access to 10 | * specific functions. 11 | * 12 | * By default, the owner account will be the one that deploys the contract. This 13 | * can later be changed with {transferOwnership}. 14 | * 15 | * This module is used through inheritance. It will make available the modifier 16 | * `onlyOwner`, which can be applied to your functions to restrict their use to 17 | * the owner. 18 | */ 19 | contract Ownable is Context { 20 | address private _owner; 21 | 22 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 23 | 24 | /** 25 | * @dev Initializes the contract setting the deployer as the initial owner. 26 | */ 27 | constructor() internal { 28 | address msgSender = _msgSender(); 29 | _owner = msgSender; 30 | emit OwnershipTransferred(address(0), msgSender); 31 | } 32 | 33 | /** 34 | * @dev Returns the address of the current owner. 35 | */ 36 | function owner() public view returns (address) { 37 | return _owner; 38 | } 39 | 40 | /** 41 | * @dev Throws if called by any account other than the owner. 42 | */ 43 | modifier onlyOwner() { 44 | require(_owner == _msgSender(), 'Ownable: caller is not the owner'); 45 | _; 46 | } 47 | 48 | /** 49 | * @dev Leaves the contract without owner. It will not be possible to call 50 | * `onlyOwner` functions anymore. Can only be called by the current owner. 51 | * 52 | * NOTE: Renouncing ownership will leave the contract without an owner, 53 | * thereby removing any functionality that is only available to the owner. 54 | */ 55 | function renounceOwnership() public virtual onlyOwner { 56 | emit OwnershipTransferred(_owner, address(0)); 57 | _owner = address(0); 58 | } 59 | 60 | /** 61 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 62 | * Can only be called by the current owner. 63 | */ 64 | function transferOwnership(address newOwner) public virtual onlyOwner { 65 | require(newOwner != address(0), 'Ownable: new owner is the zero address'); 66 | emit OwnershipTransferred(_owner, newOwner); 67 | _owner = newOwner; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/ILendingPoolCollateralManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | /** 5 | * @title ILendingPoolCollateralManager 6 | * @author Aave 7 | * @notice Defines the actions involving management of collateral in the protocol. 8 | **/ 9 | interface ILendingPoolCollateralManager { 10 | /** 11 | * @dev Emitted when a borrower is liquidated 12 | * @param collateral The address of the collateral being liquidated 13 | * @param principal The address of the reserve 14 | * @param user The address of the user being liquidated 15 | * @param debtToCover The total amount liquidated 16 | * @param liquidatedCollateralAmount The amount of collateral being liquidated 17 | * @param liquidator The address of the liquidator 18 | * @param receiveAToken true if the liquidator wants to receive aTokens, false otherwise 19 | **/ 20 | event LiquidationCall( 21 | address indexed collateral, 22 | address indexed principal, 23 | address indexed user, 24 | uint256 debtToCover, 25 | uint256 liquidatedCollateralAmount, 26 | address liquidator, 27 | bool receiveAToken 28 | ); 29 | 30 | /** 31 | * @dev Emitted when a reserve is disabled as collateral for an user 32 | * @param reserve The address of the reserve 33 | * @param user The address of the user 34 | **/ 35 | event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); 36 | 37 | /** 38 | * @dev Emitted when a reserve is enabled as collateral for an user 39 | * @param reserve The address of the reserve 40 | * @param user The address of the user 41 | **/ 42 | event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); 43 | 44 | /** 45 | * @dev Users can invoke this function to liquidate an undercollateralized position. 46 | * @param collateral The address of the collateral to liquidated 47 | * @param principal The address of the principal reserve 48 | * @param user The address of the borrower 49 | * @param debtToCover The amount of principal that the liquidator wants to repay 50 | * @param receiveAToken true if the liquidators wants to receive the aTokens, false if 51 | * he wants to receive the underlying asset directly 52 | **/ 53 | function liquidationCall( 54 | address collateral, 55 | address principal, 56 | address user, 57 | uint256 debtToCover, 58 | bool receiveAToken 59 | ) external returns (uint256, string memory); 60 | } 61 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/upgradeability/Proxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity ^0.6.0; 3 | 4 | /** 5 | * @title Proxy 6 | * @dev Implements delegation of calls to other contracts, with proper 7 | * forwarding of return values and bubbling of failures. 8 | * It defines a fallback function that delegates all calls to the address 9 | * returned by the abstract _implementation() internal function. 10 | */ 11 | abstract contract Proxy { 12 | /** 13 | * @dev Fallback function. 14 | * Implemented entirely in `_fallback`. 15 | */ 16 | fallback() external payable { 17 | _fallback(); 18 | } 19 | 20 | /** 21 | * @return The Address of the implementation. 22 | */ 23 | function _implementation() internal view virtual returns (address); 24 | 25 | /** 26 | * @dev Delegates execution to an implementation contract. 27 | * This is a low level function that doesn't return to its internal call site. 28 | * It will return to the external caller whatever the implementation returns. 29 | * @param implementation Address to delegate. 30 | */ 31 | function _delegate(address implementation) internal { 32 | //solium-disable-next-line 33 | assembly { 34 | // Copy msg.data. We take full control of memory in this inline assembly 35 | // block because it will not return to Solidity code. We overwrite the 36 | // Solidity scratch pad at memory position 0. 37 | calldatacopy(0, 0, calldatasize()) 38 | 39 | // Call the implementation. 40 | // out and outsize are 0 because we don't know the size yet. 41 | let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) 42 | 43 | // Copy the returned data. 44 | returndatacopy(0, 0, returndatasize()) 45 | 46 | switch result 47 | // delegatecall returns 0 on error. 48 | case 0 { 49 | revert(0, returndatasize()) 50 | } 51 | default { 52 | return(0, returndatasize()) 53 | } 54 | } 55 | } 56 | 57 | /** 58 | * @dev Function that is run as the first thing in the fallback function. 59 | * Can be redefined in derived contracts to add functionality. 60 | * Redefinitions must call super._willFallback(). 61 | */ 62 | function _willFallback() internal virtual {} 63 | 64 | /** 65 | * @dev fallback implementation. 66 | * Extracted to enable manual triggering. 67 | */ 68 | function _fallback() internal { 69 | _willFallback(); 70 | _delegate(_implementation()); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/ILendingPoolAddressesProvider.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | /** 5 | * @title LendingPoolAddressesProvider contract 6 | * @dev Main registry of addresses part of or connected to the protocol, including permissioned roles 7 | * - Acting also as factory of proxies and admin of those, so with right to change its implementations 8 | * - Owned by the Aave Governance 9 | * @author Aave 10 | **/ 11 | interface ILendingPoolAddressesProvider { 12 | event MarketIdSet(string newMarketId); 13 | event LendingPoolUpdated(address indexed newAddress); 14 | event ConfigurationAdminUpdated(address indexed newAddress); 15 | event EmergencyAdminUpdated(address indexed newAddress); 16 | event LendingPoolConfiguratorUpdated(address indexed newAddress); 17 | event LendingPoolCollateralManagerUpdated(address indexed newAddress); 18 | event PriceOracleUpdated(address indexed newAddress); 19 | event LendingRateOracleUpdated(address indexed newAddress); 20 | event ProxyCreated(bytes32 id, address indexed newAddress); 21 | event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy); 22 | 23 | function getMarketId() external view returns (string memory); 24 | 25 | function setMarketId(string calldata marketId) external; 26 | 27 | function setAddress(bytes32 id, address newAddress) external; 28 | 29 | function setAddressAsProxy(bytes32 id, address impl) external; 30 | 31 | function getAddress(bytes32 id) external view returns (address); 32 | 33 | function getLendingPool() external view returns (address); 34 | 35 | function setLendingPoolImpl(address pool) external; 36 | 37 | function getLendingPoolConfigurator() external view returns (address); 38 | 39 | function setLendingPoolConfiguratorImpl(address configurator) external; 40 | 41 | function getLendingPoolCollateralManager() external view returns (address); 42 | 43 | function setLendingPoolCollateralManager(address manager) external; 44 | 45 | function getPoolAdmin() external view returns (address); 46 | 47 | function setPoolAdmin(address admin) external; 48 | 49 | function getEmergencyAdmin() external view returns (address); 50 | 51 | function setEmergencyAdmin(address admin) external; 52 | 53 | function getPriceOracle() external view returns (address); 54 | 55 | function setPriceOracle(address priceOracle) external; 56 | 57 | function getLendingRateOracle() external view returns (address); 58 | 59 | function setLendingRateOracle(address lendingRateOracle) external; 60 | } 61 | -------------------------------------------------------------------------------- /contracts/YieldFarmingStrategyFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | pragma experimental ABIEncoderV2; 4 | 5 | import { YieldFarmingStrategy } from "./YieldFarmingStrategy.sol"; 6 | 7 | // Open Zeppelin 8 | import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 9 | import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; 10 | 11 | // AAVE 12 | import { ILendingPool } from './aave-v2/interfaces/ILendingPool.sol'; 13 | import { ILendingPoolAddressesProvider } from './aave-v2/interfaces/ILendingPoolAddressesProvider.sol'; 14 | import { IAaveIncentivesController } from "./aave-v2/interfaces/IAaveIncentivesController.sol"; 15 | 16 | // Polycat.finanace 17 | import { FishToken } from "./polycat/Farm/FishToken.sol"; 18 | import { MasterChef } from "./polycat/Farm/MasterChef.sol"; 19 | 20 | /** 21 | * @title YieldFarmingStrategyFactory contract 22 | */ 23 | contract YieldFarmingStrategyFactory { 24 | 25 | address[] yieldFarmingStrategies; 26 | mapping (address => address) public strategyOwners; /// [Note]: Contract address of the YieldFarmingStrategy.sol -> User address 27 | event YieldFarmingStrategyCreated(address indexed strategyOwner, YieldFarmingStrategy indexed yieldFarmingStrategy); 28 | 29 | ILendingPoolAddressesProvider public provider; 30 | IAaveIncentivesController public incentivesController; 31 | FishToken public fishToken; 32 | MasterChef public masterChef; 33 | 34 | constructor( 35 | ILendingPoolAddressesProvider _provider, 36 | IAaveIncentivesController _incentivesController, 37 | FishToken _fishToken, 38 | MasterChef _masterChef 39 | ) public { 40 | provider = _provider; 41 | incentivesController = _incentivesController; 42 | fishToken = _fishToken; 43 | masterChef = _masterChef; 44 | } 45 | 46 | /** 47 | * @notice - Create a new YieldFarmingStrategy contract 48 | */ 49 | function createNewYieldFarmingStrategy() public returns (bool) { 50 | YieldFarmingStrategy yieldFarmingStrategy = new YieldFarmingStrategy(provider, incentivesController, fishToken, masterChef, msg.sender); 51 | address YIELD_FARMING_STRATEGY = address(yieldFarmingStrategy); 52 | 53 | // Save a YieldFarmingStrategy created into the list of all YieldFarmingStrategies 54 | yieldFarmingStrategies.push(YIELD_FARMING_STRATEGY); 55 | 56 | // Associate a owner (creator) address with a YieldFarmingStrategy created 57 | strategyOwners[YIELD_FARMING_STRATEGY] = msg.sender; 58 | 59 | // Event 60 | emit YieldFarmingStrategyCreated(msg.sender, yieldFarmingStrategy); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/contracts/Address.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | /** 5 | * @dev Collection of functions related to the address type 6 | */ 7 | library Address { 8 | /** 9 | * @dev Returns true if `account` is a contract. 10 | * 11 | * [IMPORTANT] 12 | * ==== 13 | * It is unsafe to assume that an address for which this function returns 14 | * false is an externally-owned account (EOA) and not a contract. 15 | * 16 | * Among others, `isContract` will return false for the following 17 | * types of addresses: 18 | * 19 | * - an externally-owned account 20 | * - a contract in construction 21 | * - an address where a contract will be created 22 | * - an address where a contract lived, but was destroyed 23 | * ==== 24 | */ 25 | function isContract(address account) internal view returns (bool) { 26 | // According to EIP-1052, 0x0 is the value returned for not-yet created accounts 27 | // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned 28 | // for accounts without code, i.e. `keccak256('')` 29 | bytes32 codehash; 30 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 31 | // solhint-disable-next-line no-inline-assembly 32 | assembly { 33 | codehash := extcodehash(account) 34 | } 35 | return (codehash != accountHash && codehash != 0x0); 36 | } 37 | 38 | /** 39 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 40 | * `recipient`, forwarding all available gas and reverting on errors. 41 | * 42 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 43 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 44 | * imposed by `transfer`, making them unable to receive funds via 45 | * `transfer`. {sendValue} removes this limitation. 46 | * 47 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 48 | * 49 | * IMPORTANT: because control is transferred to `recipient`, care must be 50 | * taken to not create reentrancy vulnerabilities. Consider using 51 | * {ReentrancyGuard} or the 52 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 53 | */ 54 | function sendValue(address payable recipient, uint256 amount) internal { 55 | require(address(this).balance >= amount, 'Address: insufficient balance'); 56 | 57 | // solhint-disable-next-line avoid-low-level-calls, avoid-call-value 58 | (bool success, ) = recipient.call{value: amount}(''); 59 | require(success, 'Address: unable to send value, recipient may have reverted'); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/libraries/aave-upgradeability/VersionedInitializable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | /** 5 | * @title VersionedInitializable 6 | * 7 | * @dev Helper contract to implement initializer functions. To use it, replace 8 | * the constructor with a function that has the `initializer` modifier. 9 | * WARNING: Unlike constructors, initializer functions must be manually 10 | * invoked. This applies both to deploying an Initializable contract, as well 11 | * as extending an Initializable contract via inheritance. 12 | * WARNING: When used with inheritance, manual care must be taken to not invoke 13 | * a parent initializer twice, or ensure that all initializers are idempotent, 14 | * because this is not dealt with automatically as with constructors. 15 | * 16 | * @author Aave, inspired by the OpenZeppelin Initializable contract 17 | */ 18 | abstract contract VersionedInitializable { 19 | /** 20 | * @dev Indicates that the contract has been initialized. 21 | */ 22 | uint256 private lastInitializedRevision = 0; 23 | 24 | /** 25 | * @dev Indicates that the contract is in the process of being initialized. 26 | */ 27 | bool private initializing; 28 | 29 | /** 30 | * @dev Modifier to use in the initializer function of a contract. 31 | */ 32 | modifier initializer() { 33 | uint256 revision = getRevision(); 34 | require( 35 | initializing || isConstructor() || revision > lastInitializedRevision, 36 | 'Contract instance has already been initialized' 37 | ); 38 | 39 | bool isTopLevelCall = !initializing; 40 | if (isTopLevelCall) { 41 | initializing = true; 42 | lastInitializedRevision = revision; 43 | } 44 | 45 | _; 46 | 47 | if (isTopLevelCall) { 48 | initializing = false; 49 | } 50 | } 51 | 52 | /** 53 | * @dev returns the revision number of the contract 54 | * Needs to be defined in the inherited class as a constant. 55 | **/ 56 | function getRevision() internal pure virtual returns (uint256); 57 | 58 | /** 59 | * @dev Returns true if and only if the function is running in the constructor 60 | **/ 61 | function isConstructor() private view returns (bool) { 62 | // extcodesize checks the size of the code stored in an address, and 63 | // address returns the current address. Since the code is still not 64 | // deployed when running a constructor, any checks on its code size will 65 | // yield zero, making it an effective way to detect if a contract is 66 | // under construction or not. 67 | uint256 cs; 68 | //solium-disable-next-line 69 | assembly { 70 | cs := extcodesize(address()) 71 | } 72 | return cs == 0; 73 | } 74 | 75 | // Reserved storage space to allow for layout changes in the future. 76 | uint256[50] private ______gap; 77 | } 78 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/libraries/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import '../../../dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol'; 5 | 6 | /** 7 | * @title BaseImmutableAdminUpgradeabilityProxy 8 | * @author Aave, inspired by the OpenZeppelin upgradeability proxy pattern 9 | * @dev This contract combines an upgradeability proxy with an authorization 10 | * mechanism for administrative tasks. The admin role is stored in an immutable, which 11 | * helps saving transactions costs 12 | * All external functions in this contract must be guarded by the 13 | * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity 14 | * feature proposal that would enable this to be done automatically. 15 | */ 16 | contract BaseImmutableAdminUpgradeabilityProxy is BaseUpgradeabilityProxy { 17 | address immutable ADMIN; 18 | 19 | constructor(address admin) public { 20 | ADMIN = admin; 21 | } 22 | 23 | modifier ifAdmin() { 24 | if (msg.sender == ADMIN) { 25 | _; 26 | } else { 27 | _fallback(); 28 | } 29 | } 30 | 31 | /** 32 | * @return The address of the proxy admin. 33 | */ 34 | function admin() external ifAdmin returns (address) { 35 | return ADMIN; 36 | } 37 | 38 | /** 39 | * @return The address of the implementation. 40 | */ 41 | function implementation() external ifAdmin returns (address) { 42 | return _implementation(); 43 | } 44 | 45 | /** 46 | * @dev Upgrade the backing implementation of the proxy. 47 | * Only the admin can call this function. 48 | * @param newImplementation Address of the new implementation. 49 | */ 50 | function upgradeTo(address newImplementation) external ifAdmin { 51 | _upgradeTo(newImplementation); 52 | } 53 | 54 | /** 55 | * @dev Upgrade the backing implementation of the proxy and call a function 56 | * on the new implementation. 57 | * This is useful to initialize the proxied contract. 58 | * @param newImplementation Address of the new implementation. 59 | * @param data Data to send as msg.data in the low level call. 60 | * It should include the signature and the parameters of the function to be called, as described in 61 | * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. 62 | */ 63 | function upgradeToAndCall(address newImplementation, bytes calldata data) 64 | external 65 | payable 66 | ifAdmin 67 | { 68 | _upgradeTo(newImplementation); 69 | (bool success, ) = newImplementation.delegatecall(data); 70 | require(success); 71 | } 72 | 73 | /** 74 | * @dev Only fall back when the sender is not the admin. 75 | */ 76 | function _willFallback() internal virtual override { 77 | require(msg.sender != ADMIN, 'Cannot call fallback function from the proxy admin'); 78 | super._willFallback(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/contracts/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | /** 5 | * @dev Interface of the ERC20 standard as defined in the EIP. 6 | */ 7 | interface IERC20 { 8 | /** 9 | * @dev Returns the amount of tokens in existence. 10 | */ 11 | function totalSupply() external view returns (uint256); 12 | 13 | /** 14 | * @dev Returns the amount of tokens owned by `account`. 15 | */ 16 | function balanceOf(address account) external view returns (uint256); 17 | 18 | /** 19 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 20 | * 21 | * Returns a boolean value indicating whether the operation succeeded. 22 | * 23 | * Emits a {Transfer} event. 24 | */ 25 | function transfer(address recipient, uint256 amount) external returns (bool); 26 | 27 | /** 28 | * @dev Returns the remaining number of tokens that `spender` will be 29 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 30 | * zero by default. 31 | * 32 | * This value changes when {approve} or {transferFrom} are called. 33 | */ 34 | function allowance(address owner, address spender) external view returns (uint256); 35 | 36 | /** 37 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 38 | * 39 | * Returns a boolean value indicating whether the operation succeeded. 40 | * 41 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 42 | * that someone may use both the old and the new allowance by unfortunate 43 | * transaction ordering. One possible solution to mitigate this race 44 | * condition is to first reduce the spender's allowance to 0 and set the 45 | * desired value afterwards: 46 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 47 | * 48 | * Emits an {Approval} event. 49 | */ 50 | function approve(address spender, uint256 amount) external returns (bool); 51 | 52 | /** 53 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 54 | * allowance mechanism. `amount` is then deducted from the caller's 55 | * allowance. 56 | * 57 | * Returns a boolean value indicating whether the operation succeeded. 58 | * 59 | * Emits a {Transfer} event. 60 | */ 61 | function transferFrom( 62 | address sender, 63 | address recipient, 64 | uint256 amount 65 | ) external returns (bool); 66 | 67 | /** 68 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 69 | * another (`to`). 70 | * 71 | * Note that `value` may be zero. 72 | */ 73 | event Transfer(address indexed from, address indexed to, uint256 value); 74 | 75 | /** 76 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 77 | * a call to {approve}. `value` is the new allowance. 78 | */ 79 | event Approval(address indexed owner, address indexed spender, uint256 value); 80 | } 81 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/libraries/math/MathUtils.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {SafeMath} from '../../../dependencies/openzeppelin/contracts/SafeMath.sol'; 5 | import {WadRayMath} from './WadRayMath.sol'; 6 | 7 | library MathUtils { 8 | using SafeMath for uint256; 9 | using WadRayMath for uint256; 10 | 11 | /// @dev Ignoring leap years 12 | uint256 internal constant SECONDS_PER_YEAR = 365 days; 13 | 14 | /** 15 | * @dev Function to calculate the interest accumulated using a linear interest rate formula 16 | * @param rate The interest rate, in ray 17 | * @param lastUpdateTimestamp The timestamp of the last update of the interest 18 | * @return The interest rate linearly accumulated during the timeDelta, in ray 19 | **/ 20 | 21 | function calculateLinearInterest(uint256 rate, uint40 lastUpdateTimestamp) 22 | internal 23 | view 24 | returns (uint256) 25 | { 26 | //solium-disable-next-line 27 | uint256 timeDifference = block.timestamp.sub(uint256(lastUpdateTimestamp)); 28 | 29 | return (rate.mul(timeDifference) / SECONDS_PER_YEAR).add(WadRayMath.ray()); 30 | } 31 | 32 | /** 33 | * @dev Function to calculate the interest using a compounded interest rate formula 34 | * To avoid expensive exponentiation, the calculation is performed using a binomial approximation: 35 | * 36 | * (1+x)^n = 1+n*x+[n/2*(n-1)]*x^2+[n/6*(n-1)*(n-2)*x^3... 37 | * 38 | * The approximation slightly underpays liquidity providers and undercharges borrowers, with the advantage of great gas cost reductions 39 | * The whitepaper contains reference to the approximation and a table showing the margin of error per different time periods 40 | * 41 | * @param rate The interest rate, in ray 42 | * @param lastUpdateTimestamp The timestamp of the last update of the interest 43 | * @return The interest rate compounded during the timeDelta, in ray 44 | **/ 45 | function calculateCompoundedInterest( 46 | uint256 rate, 47 | uint40 lastUpdateTimestamp, 48 | uint256 currentTimestamp 49 | ) internal pure returns (uint256) { 50 | //solium-disable-next-line 51 | uint256 exp = currentTimestamp.sub(uint256(lastUpdateTimestamp)); 52 | 53 | if (exp == 0) { 54 | return WadRayMath.ray(); 55 | } 56 | 57 | uint256 expMinusOne = exp - 1; 58 | 59 | uint256 expMinusTwo = exp > 2 ? exp - 2 : 0; 60 | 61 | uint256 ratePerSecond = rate / SECONDS_PER_YEAR; 62 | 63 | uint256 basePowerTwo = ratePerSecond.rayMul(ratePerSecond); 64 | uint256 basePowerThree = basePowerTwo.rayMul(ratePerSecond); 65 | 66 | uint256 secondTerm = exp.mul(expMinusOne).mul(basePowerTwo) / 2; 67 | uint256 thirdTerm = exp.mul(expMinusOne).mul(expMinusTwo).mul(basePowerThree) / 6; 68 | 69 | return WadRayMath.ray().add(ratePerSecond.mul(exp)).add(secondTerm).add(thirdTerm); 70 | } 71 | 72 | /** 73 | * @dev Calculates the compounded interest between the timestamp of the last update and the current block timestamp 74 | * @param rate The interest rate (in ray) 75 | * @param lastUpdateTimestamp The timestamp from which the interest accumulation needs to be calculated 76 | **/ 77 | function calculateCompoundedInterest(uint256 rate, uint40 lastUpdateTimestamp) 78 | internal 79 | view 80 | returns (uint256) 81 | { 82 | return calculateCompoundedInterest(rate, lastUpdateTimestamp, block.timestamp); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/configuration/LendingPoolAddressesProviderRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; 5 | import { 6 | ILendingPoolAddressesProviderRegistry 7 | } from '../../interfaces/ILendingPoolAddressesProviderRegistry.sol'; 8 | import {Errors} from '../libraries/helpers/Errors.sol'; 9 | 10 | /** 11 | * @title LendingPoolAddressesProviderRegistry contract 12 | * @dev Main registry of LendingPoolAddressesProvider of multiple Aave protocol's markets 13 | * - Used for indexing purposes of Aave protocol's markets 14 | * - The id assigned to a LendingPoolAddressesProvider refers to the market it is connected with, 15 | * for example with `0` for the Aave main market and `1` for the next created 16 | * @author Aave 17 | **/ 18 | contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesProviderRegistry { 19 | mapping(address => uint256) private _addressesProviders; 20 | address[] private _addressesProvidersList; 21 | 22 | /** 23 | * @dev Returns the list of registered addresses provider 24 | * @return The list of addresses provider, potentially containing address(0) elements 25 | **/ 26 | function getAddressesProvidersList() external view override returns (address[] memory) { 27 | address[] memory addressesProvidersList = _addressesProvidersList; 28 | 29 | uint256 maxLength = addressesProvidersList.length; 30 | 31 | address[] memory activeProviders = new address[](maxLength); 32 | 33 | for (uint256 i = 0; i < maxLength; i++) { 34 | if (_addressesProviders[addressesProvidersList[i]] > 0) { 35 | activeProviders[i] = addressesProvidersList[i]; 36 | } 37 | } 38 | 39 | return activeProviders; 40 | } 41 | 42 | /** 43 | * @dev Registers an addresses provider 44 | * @param provider The address of the new LendingPoolAddressesProvider 45 | * @param id The id for the new LendingPoolAddressesProvider, referring to the market it belongs to 46 | **/ 47 | function registerAddressesProvider(address provider, uint256 id) external override onlyOwner { 48 | require(id != 0, Errors.LPAPR_INVALID_ADDRESSES_PROVIDER_ID); 49 | 50 | _addressesProviders[provider] = id; 51 | _addToAddressesProvidersList(provider); 52 | emit AddressesProviderRegistered(provider); 53 | } 54 | 55 | /** 56 | * @dev Removes a LendingPoolAddressesProvider from the list of registered addresses provider 57 | * @param provider The LendingPoolAddressesProvider address 58 | **/ 59 | function unregisterAddressesProvider(address provider) external override onlyOwner { 60 | require(_addressesProviders[provider] > 0, Errors.LPAPR_PROVIDER_NOT_REGISTERED); 61 | _addressesProviders[provider] = 0; 62 | emit AddressesProviderUnregistered(provider); 63 | } 64 | 65 | /** 66 | * @dev Returns the id on a registered LendingPoolAddressesProvider 67 | * @return The id or 0 if the LendingPoolAddressesProvider is not registered 68 | */ 69 | function getAddressesProviderIdByAddress(address addressesProvider) 70 | external 71 | view 72 | override 73 | returns (uint256) 74 | { 75 | return _addressesProviders[addressesProvider]; 76 | } 77 | 78 | function _addToAddressesProvidersList(address provider) internal { 79 | uint256 providersCount = _addressesProvidersList.length; 80 | 81 | for (uint256 i = 0; i < providersCount; i++) { 82 | if (_addressesProvidersList[i] == provider) { 83 | return; 84 | } 85 | } 86 | 87 | _addressesProvidersList.push(provider); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/libraries/math/WadRayMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {Errors} from '../helpers/Errors.sol'; 5 | 6 | /** 7 | * @title WadRayMath library 8 | * @author Aave 9 | * @dev Provides mul and div function for wads (decimal numbers with 18 digits precision) and rays (decimals with 27 digits) 10 | **/ 11 | 12 | library WadRayMath { 13 | uint256 internal constant WAD = 1e18; 14 | uint256 internal constant halfWAD = WAD / 2; 15 | 16 | uint256 internal constant RAY = 1e27; 17 | uint256 internal constant halfRAY = RAY / 2; 18 | 19 | uint256 internal constant WAD_RAY_RATIO = 1e9; 20 | 21 | /** 22 | * @return One ray, 1e27 23 | **/ 24 | function ray() internal pure returns (uint256) { 25 | return RAY; 26 | } 27 | 28 | /** 29 | * @return One wad, 1e18 30 | **/ 31 | 32 | function wad() internal pure returns (uint256) { 33 | return WAD; 34 | } 35 | 36 | /** 37 | * @return Half ray, 1e27/2 38 | **/ 39 | function halfRay() internal pure returns (uint256) { 40 | return halfRAY; 41 | } 42 | 43 | /** 44 | * @return Half ray, 1e18/2 45 | **/ 46 | function halfWad() internal pure returns (uint256) { 47 | return halfWAD; 48 | } 49 | 50 | /** 51 | * @dev Multiplies two wad, rounding half up to the nearest wad 52 | * @param a Wad 53 | * @param b Wad 54 | * @return The result of a*b, in wad 55 | **/ 56 | function wadMul(uint256 a, uint256 b) internal pure returns (uint256) { 57 | if (a == 0 || b == 0) { 58 | return 0; 59 | } 60 | 61 | require(a <= (type(uint256).max - halfWAD) / b, Errors.MATH_MULTIPLICATION_OVERFLOW); 62 | 63 | return (a * b + halfWAD) / WAD; 64 | } 65 | 66 | /** 67 | * @dev Divides two wad, rounding half up to the nearest wad 68 | * @param a Wad 69 | * @param b Wad 70 | * @return The result of a/b, in wad 71 | **/ 72 | function wadDiv(uint256 a, uint256 b) internal pure returns (uint256) { 73 | require(b != 0, Errors.MATH_DIVISION_BY_ZERO); 74 | uint256 halfB = b / 2; 75 | 76 | require(a <= (type(uint256).max - halfB) / WAD, Errors.MATH_MULTIPLICATION_OVERFLOW); 77 | 78 | return (a * WAD + halfB) / b; 79 | } 80 | 81 | /** 82 | * @dev Multiplies two ray, rounding half up to the nearest ray 83 | * @param a Ray 84 | * @param b Ray 85 | * @return The result of a*b, in ray 86 | **/ 87 | function rayMul(uint256 a, uint256 b) internal pure returns (uint256) { 88 | if (a == 0 || b == 0) { 89 | return 0; 90 | } 91 | 92 | require(a <= (type(uint256).max - halfRAY) / b, Errors.MATH_MULTIPLICATION_OVERFLOW); 93 | 94 | return (a * b + halfRAY) / RAY; 95 | } 96 | 97 | /** 98 | * @dev Divides two ray, rounding half up to the nearest ray 99 | * @param a Ray 100 | * @param b Ray 101 | * @return The result of a/b, in ray 102 | **/ 103 | function rayDiv(uint256 a, uint256 b) internal pure returns (uint256) { 104 | require(b != 0, Errors.MATH_DIVISION_BY_ZERO); 105 | uint256 halfB = b / 2; 106 | 107 | require(a <= (type(uint256).max - halfB) / RAY, Errors.MATH_MULTIPLICATION_OVERFLOW); 108 | 109 | return (a * RAY + halfB) / b; 110 | } 111 | 112 | /** 113 | * @dev Casts ray down to wad 114 | * @param a Ray 115 | * @return a casted to wad, rounded half up to the nearest wad 116 | **/ 117 | function rayToWad(uint256 a) internal pure returns (uint256) { 118 | uint256 halfRatio = WAD_RAY_RATIO / 2; 119 | uint256 result = halfRatio + a; 120 | require(result >= halfRatio, Errors.MATH_ADDITION_OVERFLOW); 121 | 122 | return result / WAD_RAY_RATIO; 123 | } 124 | 125 | /** 126 | * @dev Converts wad up to ray 127 | * @param a Wad 128 | * @return a converted in ray 129 | **/ 130 | function wadToRay(uint256 a) internal pure returns (uint256) { 131 | uint256 result = a * WAD_RAY_RATIO; 132 | require(result / WAD_RAY_RATIO == a, Errors.MATH_MULTIPLICATION_OVERFLOW); 133 | return result; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IAToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; 5 | import {IScaledBalanceToken} from './IScaledBalanceToken.sol'; 6 | import {IInitializableAToken} from './IInitializableAToken.sol'; 7 | import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; 8 | 9 | interface IAToken is IERC20, IScaledBalanceToken, IInitializableAToken { 10 | /** 11 | * @dev Emitted after the mint action 12 | * @param from The address performing the mint 13 | * @param value The amount being 14 | * @param index The new liquidity index of the reserve 15 | **/ 16 | event Mint(address indexed from, uint256 value, uint256 index); 17 | 18 | /** 19 | * @dev Mints `amount` aTokens to `user` 20 | * @param user The address receiving the minted tokens 21 | * @param amount The amount of tokens getting minted 22 | * @param index The new liquidity index of the reserve 23 | * @return `true` if the the previous balance of the user was 0 24 | */ 25 | function mint( 26 | address user, 27 | uint256 amount, 28 | uint256 index 29 | ) external returns (bool); 30 | 31 | /** 32 | * @dev Emitted after aTokens are burned 33 | * @param from The owner of the aTokens, getting them burned 34 | * @param target The address that will receive the underlying 35 | * @param value The amount being burned 36 | * @param index The new liquidity index of the reserve 37 | **/ 38 | event Burn(address indexed from, address indexed target, uint256 value, uint256 index); 39 | 40 | /** 41 | * @dev Emitted during the transfer action 42 | * @param from The user whose tokens are being transferred 43 | * @param to The recipient 44 | * @param value The amount being transferred 45 | * @param index The new liquidity index of the reserve 46 | **/ 47 | event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index); 48 | 49 | /** 50 | * @dev Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying` 51 | * @param user The owner of the aTokens, getting them burned 52 | * @param receiverOfUnderlying The address that will receive the underlying 53 | * @param amount The amount being burned 54 | * @param index The new liquidity index of the reserve 55 | **/ 56 | function burn( 57 | address user, 58 | address receiverOfUnderlying, 59 | uint256 amount, 60 | uint256 index 61 | ) external; 62 | 63 | /** 64 | * @dev Mints aTokens to the reserve treasury 65 | * @param amount The amount of tokens getting minted 66 | * @param index The new liquidity index of the reserve 67 | */ 68 | function mintToTreasury(uint256 amount, uint256 index) external; 69 | 70 | /** 71 | * @dev Transfers aTokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken 72 | * @param from The address getting liquidated, current owner of the aTokens 73 | * @param to The recipient 74 | * @param value The amount of tokens getting transferred 75 | **/ 76 | function transferOnLiquidation( 77 | address from, 78 | address to, 79 | uint256 value 80 | ) external; 81 | 82 | /** 83 | * @dev Transfers the underlying asset to `target`. Used by the LendingPool to transfer 84 | * assets in borrow(), withdraw() and flashLoan() 85 | * @param user The recipient of the underlying 86 | * @param amount The amount getting transferred 87 | * @return The amount transferred 88 | **/ 89 | function transferUnderlyingTo(address user, uint256 amount) external returns (uint256); 90 | 91 | /** 92 | * @dev Invoked to execute actions on the aToken side after a repayment. 93 | * @param user The user executing the repayment 94 | * @param amount The amount getting repaid 95 | **/ 96 | function handleRepayment(address user, uint256 amount) external; 97 | 98 | /** 99 | * @dev Returns the address of the incentives controller contract 100 | **/ 101 | function getIncentivesController() external view returns (IAaveIncentivesController); 102 | 103 | /** 104 | * @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH) 105 | **/ 106 | function UNDERLYING_ASSET_ADDRESS() external view returns (address); 107 | } 108 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/upgradeability/BaseAdminUpgradeabilityProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import './UpgradeabilityProxy.sol'; 5 | 6 | /** 7 | * @title BaseAdminUpgradeabilityProxy 8 | * @dev This contract combines an upgradeability proxy with an authorization 9 | * mechanism for administrative tasks. 10 | * All external functions in this contract must be guarded by the 11 | * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity 12 | * feature proposal that would enable this to be done automatically. 13 | */ 14 | contract BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy { 15 | /** 16 | * @dev Emitted when the administration has been transferred. 17 | * @param previousAdmin Address of the previous admin. 18 | * @param newAdmin Address of the new admin. 19 | */ 20 | event AdminChanged(address previousAdmin, address newAdmin); 21 | 22 | /** 23 | * @dev Storage slot with the admin of the contract. 24 | * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is 25 | * validated in the constructor. 26 | */ 27 | bytes32 internal constant ADMIN_SLOT = 28 | 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; 29 | 30 | /** 31 | * @dev Modifier to check whether the `msg.sender` is the admin. 32 | * If it is, it will run the function. Otherwise, it will delegate the call 33 | * to the implementation. 34 | */ 35 | modifier ifAdmin() { 36 | if (msg.sender == _admin()) { 37 | _; 38 | } else { 39 | _fallback(); 40 | } 41 | } 42 | 43 | /** 44 | * @return The address of the proxy admin. 45 | */ 46 | function admin() external ifAdmin returns (address) { 47 | return _admin(); 48 | } 49 | 50 | /** 51 | * @return The address of the implementation. 52 | */ 53 | function implementation() external ifAdmin returns (address) { 54 | return _implementation(); 55 | } 56 | 57 | /** 58 | * @dev Changes the admin of the proxy. 59 | * Only the current admin can call this function. 60 | * @param newAdmin Address to transfer proxy administration to. 61 | */ 62 | function changeAdmin(address newAdmin) external ifAdmin { 63 | require(newAdmin != address(0), 'Cannot change the admin of a proxy to the zero address'); 64 | emit AdminChanged(_admin(), newAdmin); 65 | _setAdmin(newAdmin); 66 | } 67 | 68 | /** 69 | * @dev Upgrade the backing implementation of the proxy. 70 | * Only the admin can call this function. 71 | * @param newImplementation Address of the new implementation. 72 | */ 73 | function upgradeTo(address newImplementation) external ifAdmin { 74 | _upgradeTo(newImplementation); 75 | } 76 | 77 | /** 78 | * @dev Upgrade the backing implementation of the proxy and call a function 79 | * on the new implementation. 80 | * This is useful to initialize the proxied contract. 81 | * @param newImplementation Address of the new implementation. 82 | * @param data Data to send as msg.data in the low level call. 83 | * It should include the signature and the parameters of the function to be called, as described in 84 | * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. 85 | */ 86 | function upgradeToAndCall(address newImplementation, bytes calldata data) 87 | external 88 | payable 89 | ifAdmin 90 | { 91 | _upgradeTo(newImplementation); 92 | (bool success, ) = newImplementation.delegatecall(data); 93 | require(success); 94 | } 95 | 96 | /** 97 | * @return adm The admin slot. 98 | */ 99 | function _admin() internal view returns (address adm) { 100 | bytes32 slot = ADMIN_SLOT; 101 | //solium-disable-next-line 102 | assembly { 103 | adm := sload(slot) 104 | } 105 | } 106 | 107 | /** 108 | * @dev Sets the address of the proxy admin. 109 | * @param newAdmin Address of the new proxy admin. 110 | */ 111 | function _setAdmin(address newAdmin) internal { 112 | bytes32 slot = ADMIN_SLOT; 113 | //solium-disable-next-line 114 | assembly { 115 | sstore(slot, newAdmin) 116 | } 117 | } 118 | 119 | /** 120 | * @dev Only fall back when the sender is not the admin. 121 | */ 122 | function _willFallback() internal virtual override { 123 | require(msg.sender != _admin(), 'Cannot call fallback function from the proxy admin'); 124 | super._willFallback(); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/tokenization/base/DebtTokenBase.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {ILendingPool} from '../../../interfaces/ILendingPool.sol'; 5 | import {ICreditDelegationToken} from '../../../interfaces/ICreditDelegationToken.sol'; 6 | import { 7 | VersionedInitializable 8 | } from '../../libraries/aave-upgradeability/VersionedInitializable.sol'; 9 | import {IncentivizedERC20} from '../IncentivizedERC20.sol'; 10 | import {Errors} from '../../libraries/helpers/Errors.sol'; 11 | 12 | /** 13 | * @title DebtTokenBase 14 | * @notice Base contract for different types of debt tokens, like StableDebtToken or VariableDebtToken 15 | * @author Aave 16 | */ 17 | 18 | abstract contract DebtTokenBase is 19 | IncentivizedERC20('DEBTTOKEN_IMPL', 'DEBTTOKEN_IMPL', 0), 20 | VersionedInitializable, 21 | ICreditDelegationToken 22 | { 23 | mapping(address => mapping(address => uint256)) internal _borrowAllowances; 24 | 25 | /** 26 | * @dev Only lending pool can call functions marked by this modifier 27 | **/ 28 | modifier onlyLendingPool { 29 | require(_msgSender() == address(_getLendingPool()), Errors.CT_CALLER_MUST_BE_LENDING_POOL); 30 | _; 31 | } 32 | 33 | /** 34 | * @dev delegates borrowing power to a user on the specific debt token 35 | * @param delegatee the address receiving the delegated borrowing power 36 | * @param amount the maximum amount being delegated. Delegation will still 37 | * respect the liquidation constraints (even if delegated, a delegatee cannot 38 | * force a delegator HF to go below 1) 39 | **/ 40 | function approveDelegation(address delegatee, uint256 amount) external override { 41 | _borrowAllowances[_msgSender()][delegatee] = amount; 42 | emit BorrowAllowanceDelegated(_msgSender(), delegatee, _getUnderlyingAssetAddress(), amount); 43 | } 44 | 45 | /** 46 | * @dev returns the borrow allowance of the user 47 | * @param fromUser The user to giving allowance 48 | * @param toUser The user to give allowance to 49 | * @return the current allowance of toUser 50 | **/ 51 | function borrowAllowance(address fromUser, address toUser) 52 | external 53 | view 54 | override 55 | returns (uint256) 56 | { 57 | return _borrowAllowances[fromUser][toUser]; 58 | } 59 | 60 | /** 61 | * @dev Being non transferrable, the debt token does not implement any of the 62 | * standard ERC20 functions for transfer and allowance. 63 | **/ 64 | function transfer(address recipient, uint256 amount) public virtual override returns (bool) { 65 | recipient; 66 | amount; 67 | revert('TRANSFER_NOT_SUPPORTED'); 68 | } 69 | 70 | function allowance(address owner, address spender) 71 | public 72 | view 73 | virtual 74 | override 75 | returns (uint256) 76 | { 77 | owner; 78 | spender; 79 | revert('ALLOWANCE_NOT_SUPPORTED'); 80 | } 81 | 82 | function approve(address spender, uint256 amount) public virtual override returns (bool) { 83 | spender; 84 | amount; 85 | revert('APPROVAL_NOT_SUPPORTED'); 86 | } 87 | 88 | function transferFrom( 89 | address sender, 90 | address recipient, 91 | uint256 amount 92 | ) public virtual override returns (bool) { 93 | sender; 94 | recipient; 95 | amount; 96 | revert('TRANSFER_NOT_SUPPORTED'); 97 | } 98 | 99 | function increaseAllowance(address spender, uint256 addedValue) 100 | public 101 | virtual 102 | override 103 | returns (bool) 104 | { 105 | spender; 106 | addedValue; 107 | revert('ALLOWANCE_NOT_SUPPORTED'); 108 | } 109 | 110 | function decreaseAllowance(address spender, uint256 subtractedValue) 111 | public 112 | virtual 113 | override 114 | returns (bool) 115 | { 116 | spender; 117 | subtractedValue; 118 | revert('ALLOWANCE_NOT_SUPPORTED'); 119 | } 120 | 121 | function _decreaseBorrowAllowance( 122 | address delegator, 123 | address delegatee, 124 | uint256 amount 125 | ) internal { 126 | uint256 newAllowance = 127 | _borrowAllowances[delegator][delegatee].sub(amount, Errors.BORROW_ALLOWANCE_NOT_ENOUGH); 128 | 129 | _borrowAllowances[delegator][delegatee] = newAllowance; 130 | 131 | emit BorrowAllowanceDelegated(delegator, delegatee, _getUnderlyingAssetAddress(), newAllowance); 132 | } 133 | 134 | function _getUnderlyingAssetAddress() internal view virtual returns (address); 135 | 136 | function _getLendingPool() internal view virtual returns (ILendingPool); 137 | } 138 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/libraries/configuration/UserConfiguration.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {Errors} from '../helpers/Errors.sol'; 5 | import {DataTypes} from '../types/DataTypes.sol'; 6 | 7 | /** 8 | * @title UserConfiguration library 9 | * @author Aave 10 | * @notice Implements the bitmap logic to handle the user configuration 11 | */ 12 | library UserConfiguration { 13 | uint256 internal constant BORROWING_MASK = 14 | 0x5555555555555555555555555555555555555555555555555555555555555555; 15 | 16 | /** 17 | * @dev Sets if the user is borrowing the reserve identified by reserveIndex 18 | * @param self The configuration object 19 | * @param reserveIndex The index of the reserve in the bitmap 20 | * @param borrowing True if the user is borrowing the reserve, false otherwise 21 | **/ 22 | function setBorrowing( 23 | DataTypes.UserConfigurationMap storage self, 24 | uint256 reserveIndex, 25 | bool borrowing 26 | ) internal { 27 | require(reserveIndex < 128, Errors.UL_INVALID_INDEX); 28 | self.data = 29 | (self.data & ~(1 << (reserveIndex * 2))) | 30 | (uint256(borrowing ? 1 : 0) << (reserveIndex * 2)); 31 | } 32 | 33 | /** 34 | * @dev Sets if the user is using as collateral the reserve identified by reserveIndex 35 | * @param self The configuration object 36 | * @param reserveIndex The index of the reserve in the bitmap 37 | * @param usingAsCollateral True if the user is usin the reserve as collateral, false otherwise 38 | **/ 39 | function setUsingAsCollateral( 40 | DataTypes.UserConfigurationMap storage self, 41 | uint256 reserveIndex, 42 | bool usingAsCollateral 43 | ) internal { 44 | require(reserveIndex < 128, Errors.UL_INVALID_INDEX); 45 | self.data = 46 | (self.data & ~(1 << (reserveIndex * 2 + 1))) | 47 | (uint256(usingAsCollateral ? 1 : 0) << (reserveIndex * 2 + 1)); 48 | } 49 | 50 | /** 51 | * @dev Used to validate if a user has been using the reserve for borrowing or as collateral 52 | * @param self The configuration object 53 | * @param reserveIndex The index of the reserve in the bitmap 54 | * @return True if the user has been using a reserve for borrowing or as collateral, false otherwise 55 | **/ 56 | function isUsingAsCollateralOrBorrowing( 57 | DataTypes.UserConfigurationMap memory self, 58 | uint256 reserveIndex 59 | ) internal pure returns (bool) { 60 | require(reserveIndex < 128, Errors.UL_INVALID_INDEX); 61 | return (self.data >> (reserveIndex * 2)) & 3 != 0; 62 | } 63 | 64 | /** 65 | * @dev Used to validate if a user has been using the reserve for borrowing 66 | * @param self The configuration object 67 | * @param reserveIndex The index of the reserve in the bitmap 68 | * @return True if the user has been using a reserve for borrowing, false otherwise 69 | **/ 70 | function isBorrowing(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex) 71 | internal 72 | pure 73 | returns (bool) 74 | { 75 | require(reserveIndex < 128, Errors.UL_INVALID_INDEX); 76 | return (self.data >> (reserveIndex * 2)) & 1 != 0; 77 | } 78 | 79 | /** 80 | * @dev Used to validate if a user has been using the reserve as collateral 81 | * @param self The configuration object 82 | * @param reserveIndex The index of the reserve in the bitmap 83 | * @return True if the user has been using a reserve as collateral, false otherwise 84 | **/ 85 | function isUsingAsCollateral(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex) 86 | internal 87 | pure 88 | returns (bool) 89 | { 90 | require(reserveIndex < 128, Errors.UL_INVALID_INDEX); 91 | return (self.data >> (reserveIndex * 2 + 1)) & 1 != 0; 92 | } 93 | 94 | /** 95 | * @dev Used to validate if a user has been borrowing from any reserve 96 | * @param self The configuration object 97 | * @return True if the user has been borrowing any reserve, false otherwise 98 | **/ 99 | function isBorrowingAny(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { 100 | return self.data & BORROWING_MASK != 0; 101 | } 102 | 103 | /** 104 | * @dev Used to validate if a user has not been using any reserve 105 | * @param self The configuration object 106 | * @return True if the user has been borrowing any reserve, false otherwise 107 | **/ 108 | function isEmpty(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { 109 | return self.data == 0; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /test/test-local/YieldFarmingStrategy.test.js: -------------------------------------------------------------------------------- 1 | /// Using local network 2 | const Web3 = require('web3'); 3 | const web3 = new Web3(new Web3.providers.WebsocketProvider('ws://localhost:8545')) 4 | 5 | /// Openzeppelin test-helper 6 | const { time, constants, expectRevert, expectEvent } = require('@openzeppelin/test-helpers') 7 | 8 | /// web3.js related methods 9 | const { toWei, fromWei, getEvents, getCurrentBlock, getCurrentTimestamp } = require('./web3js-helper/web3jsHelper') 10 | 11 | /// Import deployed-addresses 12 | const contractAddressList = require("../../migrations/addressesList/contractAddress/contractAddress.js") 13 | const tokenAddressList = require("../../migrations/addressesList/tokenAddress/tokenAddress.js") 14 | 15 | /// Artifact of smart contracts 16 | const YieldFarmingStrategy = artifacts.require("YieldFarmingStrategy") 17 | const MasterChef = artifacts.require("MasterChef") 18 | const FishToken = artifacts.require("FishToken") 19 | const DAIMockToken = artifacts.require("DAIMockToken") 20 | 21 | /// Deployed-addresses 22 | const LENDING_POOL_ADDRESSES_PROVIDER = contractAddressList["Polygon Mumbai"]["AAVE"]["LendingPoolAddressesProvider"] 23 | //let LP_TOKEN = tokenAddressList["Polygon Mumbai"]["AAVE"][""] 24 | 25 | 26 | /** 27 | * @notice - This is the test of YieldFarmingStrategy.sol 28 | * @notice - [Execution command]: $ truffle test ./test/test-local/YieldFarmingStrategy.test.js --network local 29 | */ 30 | contract("YieldFarmingStrategy", function(accounts) { 31 | /// Acccounts 32 | let deployer = accounts[0] 33 | let admin = accounts[0] 34 | let user1 = accounts[1] 35 | let user2 = accounts[2] 36 | let user3 = accounts[3] 37 | let devAddress = accounts[4] 38 | let feeAddress = accounts[5] 39 | let vaultAddress = accounts[6] 40 | 41 | /// Global contract instance 42 | let yieldFarmingStrategy 43 | let masterChef 44 | let fishToken 45 | let daiToken 46 | 47 | /// Global variable for each contract addresses 48 | let YIELD_FARMING_STRATEGY 49 | let MASTER_CHEF 50 | let FISH_TOKEN 51 | let DAI_TOKEN 52 | 53 | describe("\n Accounts", () => { 54 | it("Show accounts (wallet addresses) list that are used for this test", async () => { 55 | console.log('=== deployer ===', deployer) 56 | console.log('=== user1 ===', user1) 57 | console.log('=== user2 ===', user2) 58 | console.log('=== user3 ===', user3) 59 | }) 60 | }) 61 | 62 | describe("\n Setup smart-contracts", () => { 63 | it("Deploy the Fish Token", async () => { 64 | fishToken = await FishToken.new({ from: deployer }) 65 | FISH_TOKEN = fishToken.address 66 | }) 67 | 68 | it("Deploy the DAI Mock Token", async () => { 69 | daiToken = await DAIMockToken.new({ from: deployer }) 70 | DAI_TOKEN = daiToken.address 71 | }) 72 | 73 | it("Deploy the MasterChef contract", async () => { 74 | const startBlock = 1 75 | masterChef = await MasterChef.new(FISH_TOKEN, startBlock, devAddress, feeAddress, vaultAddress, { from: deployer }) 76 | MASTER_CHEF = masterChef.address 77 | }) 78 | 79 | it("Transfer ownership of the FishToken to the MasterChef contract", async () => { 80 | let txReceipt = await fishToken.transferOwnership(MASTER_CHEF, { from: deployer }) 81 | }) 82 | 83 | it("Deploy the YieldFarmingStrategy contract instance", async () => { 84 | yieldFarmingStrategy = await YieldFarmingStrategy.new(LENDING_POOL_ADDRESSES_PROVIDER, MASTER_CHEF, DAI_TOKEN, { from: deployer }) 85 | YIELD_FARMING_STRATEGY = yieldFarmingStrategy.address 86 | }) 87 | 88 | it("[Log]: Deployer-contract addresses", async () => { 89 | console.log('\n=== FISH_TOKEN ===', FISH_TOKEN) 90 | console.log('\n=== DAI_TOKEN ===', DAI_TOKEN) 91 | console.log('\n=== MASTER_CHEF ===', MASTER_CHEF) 92 | console.log('\n=== LENDING_POOL_ADDRESSES_PROVIDER ===', LENDING_POOL_ADDRESSES_PROVIDER) 93 | console.log('\n=== YIELD_FARMING_STRATEGY ===', YIELD_FARMING_STRATEGY) 94 | }) 95 | }) 96 | 97 | describe("\n Workflow of the YieldFarmingStrategy contract", () => { 98 | 99 | // it("depositSavings() in the SavingsContract.sol", async () => { 100 | // const underlying = toWei("10") 101 | // let txReceipt1 = await daiToken.approve(SAVINGS_CONTRACT, underlying, { from: deployer }) 102 | // //let txReceipt2 = await savingsContract.depositSavings(underlying, user1, { from: deployer }) 103 | // }) 104 | 105 | }) 106 | 107 | }) 108 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IAaveIncentivesController.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | pragma experimental ABIEncoderV2; 4 | 5 | interface IAaveIncentivesController { 6 | event RewardsAccrued(address indexed user, uint256 amount); 7 | 8 | event RewardsClaimed(address indexed user, address indexed to, uint256 amount); 9 | 10 | event RewardsClaimed( 11 | address indexed user, 12 | address indexed to, 13 | address indexed claimer, 14 | uint256 amount 15 | ); 16 | 17 | event ClaimerSet(address indexed user, address indexed claimer); 18 | 19 | /* 20 | * @dev Returns the configuration of the distribution for a certain asset 21 | * @param asset The address of the reference asset of the distribution 22 | * @return The asset index, the emission per second and the last updated timestamp 23 | **/ 24 | function getAssetData(address asset) 25 | external 26 | view 27 | returns ( 28 | uint256, 29 | uint256, 30 | uint256 31 | ); 32 | 33 | /** 34 | * @dev Whitelists an address to claim the rewards on behalf of another address 35 | * @param user The address of the user 36 | * @param claimer The address of the claimer 37 | */ 38 | function setClaimer(address user, address claimer) external; 39 | 40 | /** 41 | * @dev Returns the whitelisted claimer for a certain address (0x0 if not set) 42 | * @param user The address of the user 43 | * @return The claimer address 44 | */ 45 | function getClaimer(address user) external view returns (address); 46 | 47 | /** 48 | * @dev Configure assets for a certain rewards emission 49 | * @param assets The assets to incentivize 50 | * @param emissionsPerSecond The emission for each asset 51 | */ 52 | function configureAssets(address[] calldata assets, uint256[] calldata emissionsPerSecond) 53 | external; 54 | 55 | /** 56 | * @dev Called by the corresponding asset on any update that affects the rewards distribution 57 | * @param asset The address of the user 58 | * @param userBalance The balance of the user of the asset in the lending pool 59 | * @param totalSupply The total supply of the asset in the lending pool 60 | **/ 61 | function handleAction( 62 | address asset, 63 | uint256 userBalance, 64 | uint256 totalSupply 65 | ) external; 66 | 67 | /** 68 | * @dev Returns the total of rewards of an user, already accrued + not yet accrued 69 | * @param user The address of the user 70 | * @return The rewards 71 | **/ 72 | function getRewardsBalance(address[] calldata assets, address user) 73 | external 74 | view 75 | returns (uint256); 76 | 77 | /** 78 | * @dev Claims reward for an user, on all the assets of the lending pool, accumulating the pending rewards 79 | * @param amount Amount of rewards to claim 80 | * @param to Address that will be receiving the rewards 81 | * @return Rewards claimed 82 | **/ 83 | function claimRewards( 84 | address[] calldata assets, 85 | uint256 amount, 86 | address to 87 | ) external returns (uint256); 88 | 89 | /** 90 | * @dev Claims reward for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards. The caller must 91 | * be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager 92 | * @param amount Amount of rewards to claim 93 | * @param user Address to check and claim rewards 94 | * @param to Address that will be receiving the rewards 95 | * @return Rewards claimed 96 | **/ 97 | function claimRewardsOnBehalf( 98 | address[] calldata assets, 99 | uint256 amount, 100 | address user, 101 | address to 102 | ) external returns (uint256); 103 | 104 | /** 105 | * @dev returns the unclaimed rewards of the user 106 | * @param user the address of the user 107 | * @return the unclaimed user rewards 108 | */ 109 | function getUserUnclaimedRewards(address user) external view returns (uint256); 110 | 111 | /** 112 | * @dev returns the unclaimed rewards of the user 113 | * @param user the address of the user 114 | * @param asset The asset to incentivize 115 | * @return the user index for the asset 116 | */ 117 | function getUserAssetData(address user, address asset) external view returns (uint256); 118 | 119 | /** 120 | * @dev for backward compatibility with previous implementation of the Incentives controller 121 | */ 122 | function REWARD_TOKEN() external view returns (address); 123 | 124 | /** 125 | * @dev for backward compatibility with previous implementation of the Incentives controller 126 | */ 127 | function PRECISION() external view returns (uint8); 128 | 129 | /** 130 | * @dev Gets the distribution end timestamp of the emissions 131 | */ 132 | function DISTRIBUTION_END() external view returns (uint256); 133 | } 134 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/IStableDebtToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {IInitializableDebtToken} from './IInitializableDebtToken.sol'; 5 | import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; 6 | 7 | /** 8 | * @title IStableDebtToken 9 | * @notice Defines the interface for the stable debt token 10 | * @dev It does not inherit from IERC20 to save in code size 11 | * @author Aave 12 | **/ 13 | 14 | interface IStableDebtToken is IInitializableDebtToken { 15 | /** 16 | * @dev Emitted when new stable debt is minted 17 | * @param user The address of the user who triggered the minting 18 | * @param onBehalfOf The recipient of stable debt tokens 19 | * @param amount The amount minted 20 | * @param currentBalance The current balance of the user 21 | * @param balanceIncrease The increase in balance since the last action of the user 22 | * @param newRate The rate of the debt after the minting 23 | * @param avgStableRate The new average stable rate after the minting 24 | * @param newTotalSupply The new total supply of the stable debt token after the action 25 | **/ 26 | event Mint( 27 | address indexed user, 28 | address indexed onBehalfOf, 29 | uint256 amount, 30 | uint256 currentBalance, 31 | uint256 balanceIncrease, 32 | uint256 newRate, 33 | uint256 avgStableRate, 34 | uint256 newTotalSupply 35 | ); 36 | 37 | /** 38 | * @dev Emitted when new stable debt is burned 39 | * @param user The address of the user 40 | * @param amount The amount being burned 41 | * @param currentBalance The current balance of the user 42 | * @param balanceIncrease The the increase in balance since the last action of the user 43 | * @param avgStableRate The new average stable rate after the burning 44 | * @param newTotalSupply The new total supply of the stable debt token after the action 45 | **/ 46 | event Burn( 47 | address indexed user, 48 | uint256 amount, 49 | uint256 currentBalance, 50 | uint256 balanceIncrease, 51 | uint256 avgStableRate, 52 | uint256 newTotalSupply 53 | ); 54 | 55 | /** 56 | * @dev Mints debt token to the `onBehalfOf` address. 57 | * - The resulting rate is the weighted average between the rate of the new debt 58 | * and the rate of the previous debt 59 | * @param user The address receiving the borrowed underlying, being the delegatee in case 60 | * of credit delegate, or same as `onBehalfOf` otherwise 61 | * @param onBehalfOf The address receiving the debt tokens 62 | * @param amount The amount of debt tokens to mint 63 | * @param rate The rate of the debt being minted 64 | **/ 65 | function mint( 66 | address user, 67 | address onBehalfOf, 68 | uint256 amount, 69 | uint256 rate 70 | ) external returns (bool); 71 | 72 | /** 73 | * @dev Burns debt of `user` 74 | * - The resulting rate is the weighted average between the rate of the new debt 75 | * and the rate of the previous debt 76 | * @param user The address of the user getting his debt burned 77 | * @param amount The amount of debt tokens getting burned 78 | **/ 79 | function burn(address user, uint256 amount) external; 80 | 81 | /** 82 | * @dev Returns the average rate of all the stable rate loans. 83 | * @return The average stable rate 84 | **/ 85 | function getAverageStableRate() external view returns (uint256); 86 | 87 | /** 88 | * @dev Returns the stable rate of the user debt 89 | * @return The stable rate of the user 90 | **/ 91 | function getUserStableRate(address user) external view returns (uint256); 92 | 93 | /** 94 | * @dev Returns the timestamp of the last update of the user 95 | * @return The timestamp 96 | **/ 97 | function getUserLastUpdated(address user) external view returns (uint40); 98 | 99 | /** 100 | * @dev Returns the principal, the total supply and the average stable rate 101 | **/ 102 | function getSupplyData() 103 | external 104 | view 105 | returns ( 106 | uint256, 107 | uint256, 108 | uint256, 109 | uint40 110 | ); 111 | 112 | /** 113 | * @dev Returns the timestamp of the last update of the total supply 114 | * @return The timestamp 115 | **/ 116 | function getTotalSupplyLastUpdated() external view returns (uint40); 117 | 118 | /** 119 | * @dev Returns the total supply and the average stable rate 120 | **/ 121 | function getTotalSupplyAndAvgRate() external view returns (uint256, uint256); 122 | 123 | /** 124 | * @dev Returns the principal debt balance of the user 125 | * @return The debt balance of the user since the last burn/mint action 126 | **/ 127 | function principalBalanceOf(address user) external view returns (uint256); 128 | 129 | /** 130 | * @dev Returns the address of the incentives controller contract 131 | **/ 132 | function getIncentivesController() external view returns (IAaveIncentivesController); 133 | } 134 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ForceDAO Yield Farming Strategy on Polygon 2 | ## 【Introduction of the ForceDAO Yield Farming Strategy on Polygon】 3 | - This is a smart contract that deal with a yield farming strategy which use AAVE and Polycat.finance on Polygon. 4 | - A user create a new Yield Farming Strategy contract via the Yield Farming Strategy Factory contract. 5 | - A user can earn `double rewards` from the `AAVE Market` and `Polycat.finance` . 6 | (In terms of the Polycat, this smart contract assume that use the single staking pool of the Polycat.finance in order to earn rewards. By the way, rewards token on Polycat.finance is the `Fish Token` : https://polycat.finance/pools ) 7 | 8 |   9 | 10 | *** 11 | 12 | ## 【Workflow】 13 | - Diagram of workflow: 14 | ![diagram_ForceDAO](https://user-images.githubusercontent.com/19357502/124762179-963de480-df6d-11eb-95fe-0e58fc46030f.jpg) 15 | 16 |   17 | 18 | *** 19 | 20 | ## 【Remarks】 21 | - Versions 22 | - Solidity (Solc): v0.6.12 23 | - Truffle: v5.1.60 24 | - web3.js: v1.2.9 25 | - openzeppelin-solidity: v3.4.1 26 | - ganache-cli: v6.9.1 (ganache-core: 2.10.2) 27 | 28 | 29 |   30 | 31 | *** 32 | 33 | ## 【Setup】 34 | ### ① Install modules 35 | - Install npm modules in the root directory 36 | ``` 37 | npm install 38 | ``` 39 | 40 |
41 | 42 | ### ② Compile & migrate contracts (on local) 43 | ``` 44 | npm run migrate:local 45 | ``` 46 | 47 |
48 | 49 | ### 【Script for the DEMO of workflow】 50 | - 1: Get API-key from Infura 51 | https://infura.io/ 52 | 53 | - 2: Setup Add-on for Polygon Mumbai in Infura 54 | - How to setup Add-on for Polygon Mumbai in Infura: https://blog.infura.io/polygon-now-available/ 55 | 56 |
57 | 58 | - 3: Add `.env` to the root directory. 59 | - Please reference how to write from `.env.example` . (Please write 3 things below into `.env` ) 60 | - MNEMONIC (Mnemonic) 61 | - INFURA_KEY (Infura key) 62 | - DEPLOYER_ADDRESS (Deployer address) 63 | https://github.com/masaun/forceDAO-yield-farming-strategy-on-polygon/blob/main/.env.example 64 | 65 |
66 | 67 | - 4: In advance, Please check `MATIC token balance` of `executor's (user's) wallet address` . 68 | - Idealy, MATIC tokens balance is more than `1 MATIC` . 69 | - Matic fancet: https://faucet.matic.network/ (Please select Mumbai network) 70 | 71 |
72 | 73 | - 5: Get DAI on Polygon mumbai testnet by using the Fancet on Pods. 74 | (Please following this article. Especially, part of `"Getting Mumbai USDC, ETH and other faucet tokens"` in this article is explanation about the Fancet: https://blog.pods.finance/guide-connecting-mumbai-testnet-to-your-metamask-87978071aca8 ) 75 | 76 |
77 | 78 | - 6: Execute a script 79 | ``` 80 | npm run script:YieldFarmingStrategy 81 | ``` 82 | 83 |
84 | 85 | ## 【Demo Video】 86 | - This is a demo video of the script above ( https://github.com/masaun/forceDAO-yield-farming-strategy-on-polygon#-script-for-the-demo-of-workflow ). 87 | https://youtu.be/iBJ70bOmuLc 88 | 89 |
90 | 91 | 92 | ## 【Unit test (on local)】 93 | - 1: Start ganache-cli 94 | ``` 95 | $ ganache-cli -d --fork https://polygon-mainnet.infura.io/v3/{YOUR INFURA KEY}@{BLOCK_NUMBER} 96 | ``` 97 | (※ `-d` option is the option in order to be able to use same address on Ganache-CLI every time) 98 | (※ Please stop and re-start if an error of `"Returned error: project ID does not have access to archive state"` is displayed) 99 | 100 |
101 | 102 | - 2: Execute test of the smart-contracts 103 | ``` 104 | npm run test:YieldFarmingStrategy 105 | ``` 106 | ( `truffle test ./test/test-local/YieldFarmingStrategy.test.js --network local` ) 107 | 108 |
109 | 110 | ``` 111 | npm run test:MasterChef 112 | ``` 113 | ( `truffle test ./test/test-local/polycat/MasterChef.test.js --network local` ) 114 | 115 |
116 | 117 | *** 118 | 119 | ## 【References】 120 | - ForceDAO 121 | - Website: https://www.forcedao.com/ 122 | - GR10 Prize from ForceDAO: Build your own yield farming strategy on Polygon: https://gitcoin.co/issue/ForceDAO/bounties/4/100025917 123 | 124 |
125 | 126 | - AAVE 127 | - Deployed-addresses on Polygon Mumbai: https://docs.aave.com/developers/deployed-contracts/matic-polygon-market 128 | - Liquidity Mining: https://docs.aave.com/developers/guides/liquidity-mining 129 | 130 |
131 | 132 | - Polycat 133 | - dApp (Single Token Staking Pool): https://polycat.finance/pools 134 | - Smart contract (Github): https://github.com/polycatfi 135 | 136 |
137 | 138 | - Infura 139 | - How to setup Add-on for Polygon in Infura: https://blog.infura.io/polygon-now-available/ 140 | - Network address via Infura 141 | - Polygon Mainnet: `"https://polygon-mainnet.infura.io/YOUR-PROJECT-ID"` 142 | - Polygon Mumbai: `"https://polygon-mumbai.infura.io/YOUR-PROJECT-ID"` 143 | https://infura.io/docs/ethereum#section/Choose-a-Network 144 | 145 |
146 | 147 | - Fancet on Polygon Mumbai 148 | - Getting Mumbai USDC, ETH and other faucet tokens on Pods 149 | https://blog.pods.finance/guide-connecting-mumbai-testnet-to-your-metamask-87978071aca8 150 | -------------------------------------------------------------------------------- /contracts/aave-v2/dependencies/openzeppelin/contracts/SafeMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | /** 5 | * @dev Wrappers over Solidity's arithmetic operations with added overflow 6 | * checks. 7 | * 8 | * Arithmetic operations in Solidity wrap on overflow. This can easily result 9 | * in bugs, because programmers usually assume that an overflow raises an 10 | * error, which is the standard behavior in high level programming languages. 11 | * `SafeMath` restores this intuition by reverting the transaction when an 12 | * operation overflows. 13 | * 14 | * Using this library instead of the unchecked operations eliminates an entire 15 | * class of bugs, so it's recommended to use it always. 16 | */ 17 | library SafeMath { 18 | /** 19 | * @dev Returns the addition of two unsigned integers, reverting on 20 | * overflow. 21 | * 22 | * Counterpart to Solidity's `+` operator. 23 | * 24 | * Requirements: 25 | * - Addition cannot overflow. 26 | */ 27 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 28 | uint256 c = a + b; 29 | require(c >= a, 'SafeMath: addition overflow'); 30 | 31 | return c; 32 | } 33 | 34 | /** 35 | * @dev Returns the subtraction of two unsigned integers, reverting on 36 | * overflow (when the result is negative). 37 | * 38 | * Counterpart to Solidity's `-` operator. 39 | * 40 | * Requirements: 41 | * - Subtraction cannot overflow. 42 | */ 43 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 44 | return sub(a, b, 'SafeMath: subtraction overflow'); 45 | } 46 | 47 | /** 48 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 49 | * overflow (when the result is negative). 50 | * 51 | * Counterpart to Solidity's `-` operator. 52 | * 53 | * Requirements: 54 | * - Subtraction cannot overflow. 55 | */ 56 | function sub( 57 | uint256 a, 58 | uint256 b, 59 | string memory errorMessage 60 | ) internal pure returns (uint256) { 61 | require(b <= a, errorMessage); 62 | uint256 c = a - b; 63 | 64 | return c; 65 | } 66 | 67 | /** 68 | * @dev Returns the multiplication of two unsigned integers, reverting on 69 | * overflow. 70 | * 71 | * Counterpart to Solidity's `*` operator. 72 | * 73 | * Requirements: 74 | * - Multiplication cannot overflow. 75 | */ 76 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 77 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 78 | // benefit is lost if 'b' is also tested. 79 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 80 | if (a == 0) { 81 | return 0; 82 | } 83 | 84 | uint256 c = a * b; 85 | require(c / a == b, 'SafeMath: multiplication overflow'); 86 | 87 | return c; 88 | } 89 | 90 | /** 91 | * @dev Returns the integer division of two unsigned integers. Reverts on 92 | * division by zero. The result is rounded towards zero. 93 | * 94 | * Counterpart to Solidity's `/` operator. Note: this function uses a 95 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 96 | * uses an invalid opcode to revert (consuming all remaining gas). 97 | * 98 | * Requirements: 99 | * - The divisor cannot be zero. 100 | */ 101 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 102 | return div(a, b, 'SafeMath: division by zero'); 103 | } 104 | 105 | /** 106 | * @dev Returns the integer division of two unsigned integers. Reverts with custom message on 107 | * division by zero. The result is rounded towards zero. 108 | * 109 | * Counterpart to Solidity's `/` operator. Note: this function uses a 110 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 111 | * uses an invalid opcode to revert (consuming all remaining gas). 112 | * 113 | * Requirements: 114 | * - The divisor cannot be zero. 115 | */ 116 | function div( 117 | uint256 a, 118 | uint256 b, 119 | string memory errorMessage 120 | ) internal pure returns (uint256) { 121 | // Solidity only automatically asserts when dividing by 0 122 | require(b > 0, errorMessage); 123 | uint256 c = a / b; 124 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 125 | 126 | return c; 127 | } 128 | 129 | /** 130 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 131 | * Reverts when dividing by zero. 132 | * 133 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 134 | * opcode (which leaves remaining gas untouched) while Solidity uses an 135 | * invalid opcode to revert (consuming all remaining gas). 136 | * 137 | * Requirements: 138 | * - The divisor cannot be zero. 139 | */ 140 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 141 | return mod(a, b, 'SafeMath: modulo by zero'); 142 | } 143 | 144 | /** 145 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 146 | * Reverts with custom message when dividing by zero. 147 | * 148 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 149 | * opcode (which leaves remaining gas untouched) while Solidity uses an 150 | * invalid opcode to revert (consuming all remaining gas). 151 | * 152 | * Requirements: 153 | * - The divisor cannot be zero. 154 | */ 155 | function mod( 156 | uint256 a, 157 | uint256 b, 158 | string memory errorMessage 159 | ) internal pure returns (uint256) { 160 | require(b != 0, errorMessage); 161 | return a % b; 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /contracts/aave-v2/interfaces/ILendingPoolConfigurator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | pragma experimental ABIEncoderV2; 4 | 5 | interface ILendingPoolConfigurator { 6 | struct InitReserveInput { 7 | address aTokenImpl; 8 | address stableDebtTokenImpl; 9 | address variableDebtTokenImpl; 10 | uint8 underlyingAssetDecimals; 11 | address interestRateStrategyAddress; 12 | address underlyingAsset; 13 | address treasury; 14 | address incentivesController; 15 | string underlyingAssetName; 16 | string aTokenName; 17 | string aTokenSymbol; 18 | string variableDebtTokenName; 19 | string variableDebtTokenSymbol; 20 | string stableDebtTokenName; 21 | string stableDebtTokenSymbol; 22 | bytes params; 23 | } 24 | 25 | struct UpdateATokenInput { 26 | address asset; 27 | address treasury; 28 | address incentivesController; 29 | string name; 30 | string symbol; 31 | address implementation; 32 | bytes params; 33 | } 34 | 35 | struct UpdateDebtTokenInput { 36 | address asset; 37 | address incentivesController; 38 | string name; 39 | string symbol; 40 | address implementation; 41 | bytes params; 42 | } 43 | 44 | /** 45 | * @dev Emitted when a reserve is initialized. 46 | * @param asset The address of the underlying asset of the reserve 47 | * @param aToken The address of the associated aToken contract 48 | * @param stableDebtToken The address of the associated stable rate debt token 49 | * @param variableDebtToken The address of the associated variable rate debt token 50 | * @param interestRateStrategyAddress The address of the interest rate strategy for the reserve 51 | **/ 52 | event ReserveInitialized( 53 | address indexed asset, 54 | address indexed aToken, 55 | address stableDebtToken, 56 | address variableDebtToken, 57 | address interestRateStrategyAddress 58 | ); 59 | 60 | /** 61 | * @dev Emitted when borrowing is enabled on a reserve 62 | * @param asset The address of the underlying asset of the reserve 63 | * @param stableRateEnabled True if stable rate borrowing is enabled, false otherwise 64 | **/ 65 | event BorrowingEnabledOnReserve(address indexed asset, bool stableRateEnabled); 66 | 67 | /** 68 | * @dev Emitted when borrowing is disabled on a reserve 69 | * @param asset The address of the underlying asset of the reserve 70 | **/ 71 | event BorrowingDisabledOnReserve(address indexed asset); 72 | 73 | /** 74 | * @dev Emitted when the collateralization risk parameters for the specified asset are updated. 75 | * @param asset The address of the underlying asset of the reserve 76 | * @param ltv The loan to value of the asset when used as collateral 77 | * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized 78 | * @param liquidationBonus The bonus liquidators receive to liquidate this asset 79 | **/ 80 | event CollateralConfigurationChanged( 81 | address indexed asset, 82 | uint256 ltv, 83 | uint256 liquidationThreshold, 84 | uint256 liquidationBonus 85 | ); 86 | 87 | /** 88 | * @dev Emitted when stable rate borrowing is enabled on a reserve 89 | * @param asset The address of the underlying asset of the reserve 90 | **/ 91 | event StableRateEnabledOnReserve(address indexed asset); 92 | 93 | /** 94 | * @dev Emitted when stable rate borrowing is disabled on a reserve 95 | * @param asset The address of the underlying asset of the reserve 96 | **/ 97 | event StableRateDisabledOnReserve(address indexed asset); 98 | 99 | /** 100 | * @dev Emitted when a reserve is activated 101 | * @param asset The address of the underlying asset of the reserve 102 | **/ 103 | event ReserveActivated(address indexed asset); 104 | 105 | /** 106 | * @dev Emitted when a reserve is deactivated 107 | * @param asset The address of the underlying asset of the reserve 108 | **/ 109 | event ReserveDeactivated(address indexed asset); 110 | 111 | /** 112 | * @dev Emitted when a reserve is frozen 113 | * @param asset The address of the underlying asset of the reserve 114 | **/ 115 | event ReserveFrozen(address indexed asset); 116 | 117 | /** 118 | * @dev Emitted when a reserve is unfrozen 119 | * @param asset The address of the underlying asset of the reserve 120 | **/ 121 | event ReserveUnfrozen(address indexed asset); 122 | 123 | /** 124 | * @dev Emitted when a reserve factor is updated 125 | * @param asset The address of the underlying asset of the reserve 126 | * @param factor The new reserve factor 127 | **/ 128 | event ReserveFactorChanged(address indexed asset, uint256 factor); 129 | 130 | /** 131 | * @dev Emitted when the reserve decimals are updated 132 | * @param asset The address of the underlying asset of the reserve 133 | * @param decimals The new decimals 134 | **/ 135 | event ReserveDecimalsChanged(address indexed asset, uint256 decimals); 136 | 137 | /** 138 | * @dev Emitted when a reserve interest strategy contract is updated 139 | * @param asset The address of the underlying asset of the reserve 140 | * @param strategy The new address of the interest strategy contract 141 | **/ 142 | event ReserveInterestRateStrategyChanged(address indexed asset, address strategy); 143 | 144 | /** 145 | * @dev Emitted when an aToken implementation is upgraded 146 | * @param asset The address of the underlying asset of the reserve 147 | * @param proxy The aToken proxy address 148 | * @param implementation The new aToken implementation 149 | **/ 150 | event ATokenUpgraded( 151 | address indexed asset, 152 | address indexed proxy, 153 | address indexed implementation 154 | ); 155 | 156 | /** 157 | * @dev Emitted when the implementation of a stable debt token is upgraded 158 | * @param asset The address of the underlying asset of the reserve 159 | * @param proxy The stable debt token proxy address 160 | * @param implementation The new aToken implementation 161 | **/ 162 | event StableDebtTokenUpgraded( 163 | address indexed asset, 164 | address indexed proxy, 165 | address indexed implementation 166 | ); 167 | 168 | /** 169 | * @dev Emitted when the implementation of a variable debt token is upgraded 170 | * @param asset The address of the underlying asset of the reserve 171 | * @param proxy The variable debt token proxy address 172 | * @param implementation The new aToken implementation 173 | **/ 174 | event VariableDebtTokenUpgraded( 175 | address indexed asset, 176 | address indexed proxy, 177 | address indexed implementation 178 | ); 179 | } 180 | -------------------------------------------------------------------------------- /test/test-local/truffle-mint-dai/abi/usdt-abi.js: -------------------------------------------------------------------------------- 1 | module.exports = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_upgradedAddress","type":"address"}],"name":"deprecate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"deprecated","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_evilUser","type":"address"}],"name":"addBlackList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"upgradedAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balances","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maximumFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_maker","type":"address"}],"name":"getBlackListStatus","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowed","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newBasisPoints","type":"uint256"},{"name":"newMaxFee","type":"uint256"}],"name":"setParams","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"issue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"redeem","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"basisPointsRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"isBlackListed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_clearedUser","type":"address"}],"name":"removeBlackList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MAX_UINT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_blackListedUser","type":"address"}],"name":"destroyBlackFunds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_initialSupply","type":"uint256"},{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"Issue","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newAddress","type":"address"}],"name":"Deprecate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"feeBasisPoints","type":"uint256"},{"indexed":false,"name":"maxFee","type":"uint256"}],"name":"Params","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_blackListedUser","type":"address"},{"indexed":false,"name":"_balance","type":"uint256"}],"name":"DestroyedBlackFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_user","type":"address"}],"name":"AddedBlackList","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_user","type":"address"}],"name":"RemovedBlackList","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"}] 2 | -------------------------------------------------------------------------------- /contracts/polycat/Farm/IFO.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "@openzeppelin/contracts/math/SafeMath.sol"; 6 | import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; 7 | import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; 8 | 9 | import "./Governor.sol"; 10 | 11 | contract IFO is ReentrancyGuard, Governor { 12 | using SafeMath for uint256; 13 | using SafeERC20 for IERC20; 14 | 15 | // Info of each user. 16 | struct UserInfo { 17 | uint256 amount; // How many tokens the user has provided. 18 | bool claimed; // default false 19 | } 20 | 21 | uint256 public startBlock; 22 | uint256 public endBlock; 23 | uint256 public empty; 24 | 25 | // The token used to buy offeringToken e.g. USDC 26 | IERC20 public purchaseToken; 27 | uint256 public purchaseDecimal; 28 | // The token used to burn during buy e.g. FISH 29 | IERC20 public burnToken; 30 | uint256 public burnDecimal; 31 | // purchaseToken:burnToken 32 | uint256 public tokenRatio; 33 | 34 | // The offered token 35 | IERC20 public offeringToken; 36 | // The total amount of burnToken needed to buy all offeringTokens 37 | // We use burnToken as the purchaseToken amount is based on burnToken*tokenRatio 38 | uint256 public raisingAmount; 39 | // The total amount of offeringTokens to sell 40 | uint256 public offeringAmount; 41 | // Total raised amount of burnToken, can be higher than raisingAmount 42 | uint256 public totalAmount; 43 | 44 | mapping (address => UserInfo) public userInfo; 45 | address[] public addressList; 46 | 47 | 48 | event Deposit(address indexed user, uint256 amount); 49 | event Harvest(address indexed user, uint256 offeringAmount, uint256 excessAmount); 50 | 51 | constructor( 52 | IERC20 _purchaseToken, 53 | uint256 _purchaseDecimal, 54 | IERC20 _burnToken, 55 | uint256 _burnDecimal, 56 | uint256 _tokenRatio, 57 | IERC20 _offeringToken, 58 | uint256 _startBlock, 59 | uint256 _endBlock, 60 | uint256 _offeringAmount, 61 | uint256 _raisingAmount, 62 | address _govAddress 63 | ) public { 64 | purchaseToken = _purchaseToken; 65 | purchaseDecimal = _purchaseDecimal; 66 | burnToken = _burnToken; 67 | burnDecimal = _burnDecimal; 68 | tokenRatio = _tokenRatio; 69 | offeringToken = _offeringToken; 70 | startBlock = _startBlock; 71 | endBlock = _endBlock; 72 | offeringAmount = _offeringAmount; 73 | raisingAmount = _raisingAmount; 74 | govAddress = _govAddress; 75 | } 76 | 77 | function setOfferingAmount(uint256 _offerAmount) external onlyGov { 78 | require (block.number < startBlock, 'Cannot change after start'); 79 | offeringAmount = _offerAmount; 80 | } 81 | 82 | function setRaisingAmount(uint256 _raisingAmount) external onlyGov { 83 | require (block.number < startBlock, 'Cannot change after start'); 84 | raisingAmount = _raisingAmount; 85 | } 86 | 87 | function deposit(uint256 _amount) external nonReentrant { 88 | require (block.number > startBlock && block.number < endBlock, 'Has not started'); 89 | require (_amount > 0, 'Cannot deposit zero'); 90 | burnToken.safeTransferFrom(address(msg.sender), address(this), _amount); 91 | purchaseToken.safeTransferFrom(address(msg.sender), address(this), _amount.mul(tokenRatio).mul(purchaseDecimal).div(burnDecimal)); 92 | if (userInfo[msg.sender].amount == 0) { 93 | addressList.push(address(msg.sender)); 94 | } 95 | userInfo[msg.sender].amount = userInfo[msg.sender].amount.add(_amount); 96 | totalAmount = totalAmount.add(_amount); 97 | emit Deposit(msg.sender, _amount); 98 | } 99 | 100 | function harvest() external nonReentrant { 101 | require (block.number > endBlock, 'Has not ended yet'); 102 | require (userInfo[msg.sender].amount > 0, 'Have you participated?'); 103 | require (!userInfo[msg.sender].claimed, 'Nothing to harvest'); 104 | uint256 offeringTokenAmount = getOfferingAmount(msg.sender); 105 | uint256 refundingTokenAmount = getRefundingAmount(msg.sender); 106 | offeringToken.safeTransfer(address(msg.sender), offeringTokenAmount); 107 | if (refundingTokenAmount > 0) { 108 | burnToken.safeTransfer(address(msg.sender), refundingTokenAmount); 109 | purchaseToken.safeTransfer(address(msg.sender), refundingTokenAmount.mul(tokenRatio).mul(purchaseDecimal).div(burnDecimal)); 110 | } 111 | userInfo[msg.sender].claimed = true; 112 | emit Harvest(msg.sender, offeringTokenAmount, refundingTokenAmount); 113 | } 114 | 115 | function hasHarvest(address _user) external view returns(bool) { 116 | return userInfo[_user].claimed; 117 | } 118 | 119 | // allocation 100000 means 0.1(10%), 1 means 0.000001(0.0001%), 1000000 means 1(100%) 120 | function getUserAllocation(address _user) public view returns(uint256) { 121 | return userInfo[_user].amount.mul(1e36).div(totalAmount).div(1e18); 122 | } 123 | 124 | // get the amount of IFO token you will get 125 | function getOfferingAmount(address _user) public view returns(uint256) { 126 | if (totalAmount > raisingAmount) { 127 | uint256 allocation = getUserAllocation(_user); 128 | return offeringAmount.mul(allocation).div(1e18); 129 | } 130 | else { 131 | // userInfo[_user] / (raisingAmount / offeringAmount) 132 | return userInfo[_user].amount.mul(offeringAmount).div(raisingAmount); 133 | } 134 | } 135 | 136 | // get the amount of lp token you will be refunded 137 | function getRefundingAmount(address _user) public view returns(uint256) { 138 | if (totalAmount <= raisingAmount) { 139 | return 0; 140 | } 141 | uint256 allocation = getUserAllocation(_user); 142 | uint256 payAmount = raisingAmount.mul(allocation).div(1e18); 143 | return userInfo[_user].amount.sub(payAmount); 144 | } 145 | 146 | function getAddressListLength() external view returns(uint256) { 147 | return addressList.length; 148 | } 149 | 150 | function beforeWithdraw() external onlyGov { 151 | require (block.number < startBlock, 'Dont rugpull'); 152 | offeringToken.safeTransfer(address(msg.sender), offeringToken.balanceOf(address(this))); 153 | } 154 | 155 | function finalWithdraw() external onlyGov { 156 | require (block.number > endBlock, 'Dont rugpull'); 157 | if (totalAmount < raisingAmount) { 158 | burnToken.safeTransfer(address(msg.sender), totalAmount); 159 | purchaseToken.safeTransfer(address(msg.sender), totalAmount.mul(tokenRatio).mul(purchaseDecimal).div(burnDecimal)); 160 | offeringToken.safeTransfer(address(msg.sender), offeringAmount.mul(raisingAmount.sub(totalAmount)).div(raisingAmount)); 161 | } else { 162 | burnToken.safeTransfer(address(msg.sender), raisingAmount); 163 | purchaseToken.safeTransfer(address(msg.sender), raisingAmount.mul(tokenRatio).mul(purchaseDecimal).div(burnDecimal)); 164 | } 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /contracts/polycat/Farm/Timelock.sol: -------------------------------------------------------------------------------- 1 | // COPIED FROM https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/GovernorAlpha.sol 2 | // Copyright 2020 Compound Labs, Inc. 3 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | // 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 5 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 6 | // 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 7 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 8 | // 9 | // Ctrl+f for XXX to see all the modifications. 10 | 11 | // SPDX-License-Identifier: MIT 12 | pragma solidity 0.6.12; 13 | 14 | // XXX: import "./SafeMath.sol"; 15 | import "@openzeppelin/contracts/math/SafeMath.sol"; 16 | 17 | contract Timelock { 18 | using SafeMath for uint; 19 | 20 | event NewAdmin(address indexed newAdmin); 21 | event NewPendingAdmin(address indexed newPendingAdmin); 22 | event NewDelay(uint indexed newDelay); 23 | event CancelTransaction(bytes32 indexed txHash, address indexed target, uint value, string signature, bytes data, uint eta); 24 | event ExecuteTransaction(bytes32 indexed txHash, address indexed target, uint value, string signature, bytes data, uint eta); 25 | event QueueTransaction(bytes32 indexed txHash, address indexed target, uint value, string signature, bytes data, uint eta); 26 | 27 | uint public constant GRACE_PERIOD = 14 days; 28 | uint public constant MINIMUM_DELAY = 3 hours; 29 | uint public constant MAXIMUM_DELAY = 30 days; 30 | 31 | address public admin; 32 | address public pendingAdmin; 33 | uint public delay; 34 | bool public admin_initialized; 35 | 36 | mapping (bytes32 => bool) public queuedTransactions; 37 | 38 | 39 | constructor(address admin_, uint delay_) public { 40 | require(delay_ >= MINIMUM_DELAY, "Timelock::constructor: Delay must exceed minimum delay."); 41 | require(delay_ <= MAXIMUM_DELAY, "Timelock::constructor: Delay must not exceed maximum delay."); 42 | 43 | admin = admin_; 44 | delay = delay_; 45 | admin_initialized = false; 46 | } 47 | 48 | // XXX: function() external payable { } 49 | receive() external payable { } 50 | 51 | function setDelay(uint delay_) public { 52 | require(msg.sender == address(this), "Timelock::setDelay: Call must come from Timelock."); 53 | require(delay_ >= MINIMUM_DELAY, "Timelock::setDelay: Delay must exceed minimum delay."); 54 | require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay."); 55 | delay = delay_; 56 | 57 | emit NewDelay(delay); 58 | } 59 | 60 | function acceptAdmin() public { 61 | require(msg.sender == pendingAdmin, "Timelock::acceptAdmin: Call must come from pendingAdmin."); 62 | admin = msg.sender; 63 | pendingAdmin = address(0); 64 | 65 | emit NewAdmin(admin); 66 | } 67 | 68 | function setPendingAdmin(address pendingAdmin_) public { 69 | // allows one time setting of admin for deployment purposes 70 | if (admin_initialized) { 71 | require(msg.sender == address(this), "Timelock::setPendingAdmin: Call must come from Timelock."); 72 | } else { 73 | require(msg.sender == admin, "Timelock::setPendingAdmin: First call must come from admin."); 74 | admin_initialized = true; 75 | } 76 | pendingAdmin = pendingAdmin_; 77 | 78 | emit NewPendingAdmin(pendingAdmin); 79 | } 80 | 81 | function queueTransaction(address target, uint value, string memory signature, bytes memory data, uint eta) public returns (bytes32) { 82 | require(msg.sender == admin, "Timelock::queueTransaction: Call must come from admin."); 83 | require(eta >= getBlockTimestamp().add(delay), "Timelock::queueTransaction: Estimated execution block must satisfy delay."); 84 | 85 | bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); 86 | queuedTransactions[txHash] = true; 87 | 88 | emit QueueTransaction(txHash, target, value, signature, data, eta); 89 | return txHash; 90 | } 91 | 92 | function cancelTransaction(address target, uint value, string memory signature, bytes memory data, uint eta) public { 93 | require(msg.sender == admin, "Timelock::cancelTransaction: Call must come from admin."); 94 | 95 | bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); 96 | queuedTransactions[txHash] = false; 97 | 98 | emit CancelTransaction(txHash, target, value, signature, data, eta); 99 | } 100 | 101 | function executeTransaction(address target, uint value, string memory signature, bytes memory data, uint eta) public payable returns (bytes memory) { 102 | require(msg.sender == admin, "Timelock::executeTransaction: Call must come from admin."); 103 | 104 | bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); 105 | require(queuedTransactions[txHash], "Timelock::executeTransaction: Transaction hasn't been queued."); 106 | require(getBlockTimestamp() >= eta, "Timelock::executeTransaction: Transaction hasn't surpassed time lock."); 107 | require(getBlockTimestamp() <= eta.add(GRACE_PERIOD), "Timelock::executeTransaction: Transaction is stale."); 108 | 109 | queuedTransactions[txHash] = false; 110 | 111 | bytes memory callData; 112 | 113 | if (bytes(signature).length == 0) { 114 | callData = data; 115 | } else { 116 | callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data); 117 | } 118 | 119 | // solium-disable-next-line security/no-call-value 120 | (bool success, bytes memory returnData) = target.call.value(value)(callData); 121 | require(success, "Timelock::executeTransaction: Transaction execution reverted."); 122 | 123 | emit ExecuteTransaction(txHash, target, value, signature, data, eta); 124 | 125 | return returnData; 126 | } 127 | 128 | function getBlockTimestamp() internal view returns (uint) { 129 | // solium-disable-next-line security/no-block-members 130 | return block.timestamp; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /test/test-local/truffle-mint-dai/abi/usdc-abi.js: -------------------------------------------------------------------------------- 1 | module.exports = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_account","type":"address"}],"name":"unBlacklist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"minter","type":"address"}],"name":"removeMinter","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_currency","type":"string"},{"name":"_decimals","type":"uint8"},{"name":"_masterMinter","type":"address"},{"name":"_pauser","type":"address"},{"name":"_blacklister","type":"address"},{"name":"_owner","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"masterMinter","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"minter","type":"address"},{"name":"minterAllowedAmount","type":"uint256"}],"name":"configureMinter","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newPauser","type":"address"}],"name":"updatePauser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"minter","type":"address"}],"name":"minterAllowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pauser","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newMasterMinter","type":"address"}],"name":"updateMasterMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"isMinter","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newBlacklister","type":"address"}],"name":"updateBlacklister","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"blacklister","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currency","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_account","type":"address"}],"name":"blacklist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"isBlacklisted","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"minter","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"burner","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"minter","type":"address"},{"indexed":false,"name":"minterAllowedAmount","type":"uint256"}],"name":"MinterConfigured","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"oldMinter","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"newMasterMinter","type":"address"}],"name":"MasterMinterChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_account","type":"address"}],"name":"Blacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_account","type":"address"}],"name":"UnBlacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"newBlacklister","type":"address"}],"name":"BlacklisterChanged","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"newAddress","type":"address"}],"name":"PauserChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"previousOwner","type":"address"},{"indexed":false,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}] 2 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/tokenization/VariableDebtToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {IVariableDebtToken} from '../../interfaces/IVariableDebtToken.sol'; 5 | import {WadRayMath} from '../libraries/math/WadRayMath.sol'; 6 | import {Errors} from '../libraries/helpers/Errors.sol'; 7 | import {DebtTokenBase} from './base/DebtTokenBase.sol'; 8 | import {ILendingPool} from '../../interfaces/ILendingPool.sol'; 9 | import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol'; 10 | 11 | /** 12 | * @title VariableDebtToken 13 | * @notice Implements a variable debt token to track the borrowing positions of users 14 | * at variable rate mode 15 | * @author Aave 16 | **/ 17 | contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { 18 | using WadRayMath for uint256; 19 | 20 | uint256 public constant DEBT_TOKEN_REVISION = 0x1; 21 | 22 | ILendingPool internal _pool; 23 | address internal _underlyingAsset; 24 | IAaveIncentivesController internal _incentivesController; 25 | 26 | /** 27 | * @dev Initializes the debt token. 28 | * @param pool The address of the lending pool where this aToken will be used 29 | * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH) 30 | * @param incentivesController The smart contract managing potential incentives distribution 31 | * @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's 32 | * @param debtTokenName The name of the token 33 | * @param debtTokenSymbol The symbol of the token 34 | */ 35 | function initialize( 36 | ILendingPool pool, 37 | address underlyingAsset, 38 | IAaveIncentivesController incentivesController, 39 | uint8 debtTokenDecimals, 40 | string memory debtTokenName, 41 | string memory debtTokenSymbol, 42 | bytes calldata params 43 | ) public override initializer { 44 | _setName(debtTokenName); 45 | _setSymbol(debtTokenSymbol); 46 | _setDecimals(debtTokenDecimals); 47 | 48 | _pool = pool; 49 | _underlyingAsset = underlyingAsset; 50 | _incentivesController = incentivesController; 51 | 52 | emit Initialized( 53 | underlyingAsset, 54 | address(pool), 55 | address(incentivesController), 56 | debtTokenDecimals, 57 | debtTokenName, 58 | debtTokenSymbol, 59 | params 60 | ); 61 | } 62 | 63 | /** 64 | * @dev Gets the revision of the stable debt token implementation 65 | * @return The debt token implementation revision 66 | **/ 67 | function getRevision() internal pure virtual override returns (uint256) { 68 | return DEBT_TOKEN_REVISION; 69 | } 70 | 71 | /** 72 | * @dev Calculates the accumulated debt balance of the user 73 | * @return The debt balance of the user 74 | **/ 75 | function balanceOf(address user) public view virtual override returns (uint256) { 76 | uint256 scaledBalance = super.balanceOf(user); 77 | 78 | if (scaledBalance == 0) { 79 | return 0; 80 | } 81 | 82 | return scaledBalance.rayMul(_pool.getReserveNormalizedVariableDebt(_underlyingAsset)); 83 | } 84 | 85 | /** 86 | * @dev Mints debt token to the `onBehalfOf` address 87 | * - Only callable by the LendingPool 88 | * @param user The address receiving the borrowed underlying, being the delegatee in case 89 | * of credit delegate, or same as `onBehalfOf` otherwise 90 | * @param onBehalfOf The address receiving the debt tokens 91 | * @param amount The amount of debt being minted 92 | * @param index The variable debt index of the reserve 93 | * @return `true` if the the previous balance of the user is 0 94 | **/ 95 | function mint( 96 | address user, 97 | address onBehalfOf, 98 | uint256 amount, 99 | uint256 index 100 | ) external override onlyLendingPool returns (bool) { 101 | if (user != onBehalfOf) { 102 | _decreaseBorrowAllowance(onBehalfOf, user, amount); 103 | } 104 | 105 | uint256 previousBalance = super.balanceOf(onBehalfOf); 106 | uint256 amountScaled = amount.rayDiv(index); 107 | require(amountScaled != 0, Errors.CT_INVALID_MINT_AMOUNT); 108 | 109 | _mint(onBehalfOf, amountScaled); 110 | 111 | emit Transfer(address(0), onBehalfOf, amount); 112 | emit Mint(user, onBehalfOf, amount, index); 113 | 114 | return previousBalance == 0; 115 | } 116 | 117 | /** 118 | * @dev Burns user variable debt 119 | * - Only callable by the LendingPool 120 | * @param user The user whose debt is getting burned 121 | * @param amount The amount getting burned 122 | * @param index The variable debt index of the reserve 123 | **/ 124 | function burn( 125 | address user, 126 | uint256 amount, 127 | uint256 index 128 | ) external override onlyLendingPool { 129 | uint256 amountScaled = amount.rayDiv(index); 130 | require(amountScaled != 0, Errors.CT_INVALID_BURN_AMOUNT); 131 | 132 | _burn(user, amountScaled); 133 | 134 | emit Transfer(user, address(0), amount); 135 | emit Burn(user, amount, index); 136 | } 137 | 138 | /** 139 | * @dev Returns the principal debt balance of the user from 140 | * @return The debt balance of the user since the last burn/mint action 141 | **/ 142 | function scaledBalanceOf(address user) public view virtual override returns (uint256) { 143 | return super.balanceOf(user); 144 | } 145 | 146 | /** 147 | * @dev Returns the total supply of the variable debt token. Represents the total debt accrued by the users 148 | * @return The total supply 149 | **/ 150 | function totalSupply() public view virtual override returns (uint256) { 151 | return super.totalSupply().rayMul(_pool.getReserveNormalizedVariableDebt(_underlyingAsset)); 152 | } 153 | 154 | /** 155 | * @dev Returns the scaled total supply of the variable debt token. Represents sum(debt/index) 156 | * @return the scaled total supply 157 | **/ 158 | function scaledTotalSupply() public view virtual override returns (uint256) { 159 | return super.totalSupply(); 160 | } 161 | 162 | /** 163 | * @dev Returns the principal balance of the user and principal total supply. 164 | * @param user The address of the user 165 | * @return The principal balance of the user 166 | * @return The principal total supply 167 | **/ 168 | function getScaledUserBalanceAndSupply(address user) 169 | external 170 | view 171 | override 172 | returns (uint256, uint256) 173 | { 174 | return (super.balanceOf(user), super.totalSupply()); 175 | } 176 | 177 | /** 178 | * @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH) 179 | **/ 180 | function UNDERLYING_ASSET_ADDRESS() public view returns (address) { 181 | return _underlyingAsset; 182 | } 183 | 184 | /** 185 | * @dev Returns the address of the incentives controller contract 186 | **/ 187 | function getIncentivesController() external view override returns (IAaveIncentivesController) { 188 | return _getIncentivesController(); 189 | } 190 | 191 | /** 192 | * @dev Returns the address of the lending pool where this aToken is used 193 | **/ 194 | function POOL() public view returns (ILendingPool) { 195 | return _pool; 196 | } 197 | 198 | function _getIncentivesController() internal view override returns (IAaveIncentivesController) { 199 | return _incentivesController; 200 | } 201 | 202 | function _getUnderlyingAssetAddress() internal view override returns (address) { 203 | return _underlyingAsset; 204 | } 205 | 206 | function _getLendingPool() internal view override returns (ILendingPool) { 207 | return _pool; 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /test/test-local/truffle-mint-dai/abi/dai.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | constant: true, 4 | inputs: [], 5 | name: 'name', 6 | outputs: [{ name: '', type: 'bytes32' }], 7 | payable: false, 8 | stateMutability: 'view', 9 | type: 'function' 10 | }, 11 | { 12 | constant: false, 13 | inputs: [], 14 | name: 'stop', 15 | outputs: [], 16 | payable: false, 17 | stateMutability: 'nonpayable', 18 | type: 'function' 19 | }, 20 | { 21 | constant: false, 22 | inputs: [ 23 | { name: 'guy', type: 'address' }, 24 | { name: 'wad', type: 'uint256' } 25 | ], 26 | name: 'approve', 27 | outputs: [{ name: '', type: 'bool' }], 28 | payable: false, 29 | stateMutability: 'nonpayable', 30 | type: 'function' 31 | }, 32 | { 33 | constant: false, 34 | inputs: [{ name: 'owner_', type: 'address' }], 35 | name: 'setOwner', 36 | outputs: [], 37 | payable: false, 38 | stateMutability: 'nonpayable', 39 | type: 'function' 40 | }, 41 | { 42 | constant: true, 43 | inputs: [], 44 | name: 'totalSupply', 45 | outputs: [{ name: '', type: 'uint256' }], 46 | payable: false, 47 | stateMutability: 'view', 48 | type: 'function' 49 | }, 50 | { 51 | constant: false, 52 | inputs: [ 53 | { name: 'src', type: 'address' }, 54 | { name: 'dst', type: 'address' }, 55 | { name: 'wad', type: 'uint256' } 56 | ], 57 | name: 'transferFrom', 58 | outputs: [{ name: '', type: 'bool' }], 59 | payable: false, 60 | stateMutability: 'nonpayable', 61 | type: 'function' 62 | }, 63 | { 64 | constant: true, 65 | inputs: [], 66 | name: 'decimals', 67 | outputs: [{ name: '', type: 'uint256' }], 68 | payable: false, 69 | stateMutability: 'view', 70 | type: 'function' 71 | }, 72 | { 73 | constant: false, 74 | inputs: [ 75 | { name: 'guy', type: 'address' }, 76 | { name: 'wad', type: 'uint256' } 77 | ], 78 | name: 'mint', 79 | outputs: [], 80 | payable: false, 81 | stateMutability: 'nonpayable', 82 | type: 'function' 83 | }, 84 | { 85 | constant: false, 86 | inputs: [{ name: 'wad', type: 'uint256' }], 87 | name: 'burn', 88 | outputs: [], 89 | payable: false, 90 | stateMutability: 'nonpayable', 91 | type: 'function' 92 | }, 93 | { 94 | constant: false, 95 | inputs: [{ name: 'name_', type: 'bytes32' }], 96 | name: 'setName', 97 | outputs: [], 98 | payable: false, 99 | stateMutability: 'nonpayable', 100 | type: 'function' 101 | }, 102 | { 103 | constant: true, 104 | inputs: [{ name: 'src', type: 'address' }], 105 | name: 'balanceOf', 106 | outputs: [{ name: '', type: 'uint256' }], 107 | payable: false, 108 | stateMutability: 'view', 109 | type: 'function' 110 | }, 111 | { 112 | constant: true, 113 | inputs: [], 114 | name: 'stopped', 115 | outputs: [{ name: '', type: 'bool' }], 116 | payable: false, 117 | stateMutability: 'view', 118 | type: 'function' 119 | }, 120 | { 121 | constant: false, 122 | inputs: [{ name: 'authority_', type: 'address' }], 123 | name: 'setAuthority', 124 | outputs: [], 125 | payable: false, 126 | stateMutability: 'nonpayable', 127 | type: 'function' 128 | }, 129 | { 130 | constant: true, 131 | inputs: [], 132 | name: 'owner', 133 | outputs: [{ name: '', type: 'address' }], 134 | payable: false, 135 | stateMutability: 'view', 136 | type: 'function' 137 | }, 138 | { 139 | constant: true, 140 | inputs: [], 141 | name: 'symbol', 142 | outputs: [{ name: '', type: 'bytes32' }], 143 | payable: false, 144 | stateMutability: 'view', 145 | type: 'function' 146 | }, 147 | { 148 | constant: false, 149 | inputs: [ 150 | { name: 'guy', type: 'address' }, 151 | { name: 'wad', type: 'uint256' } 152 | ], 153 | name: 'burn', 154 | outputs: [], 155 | payable: false, 156 | stateMutability: 'nonpayable', 157 | type: 'function' 158 | }, 159 | { 160 | constant: false, 161 | inputs: [{ name: 'wad', type: 'uint256' }], 162 | name: 'mint', 163 | outputs: [], 164 | payable: false, 165 | stateMutability: 'nonpayable', 166 | type: 'function' 167 | }, 168 | { 169 | constant: false, 170 | inputs: [ 171 | { name: 'dst', type: 'address' }, 172 | { name: 'wad', type: 'uint256' } 173 | ], 174 | name: 'transfer', 175 | outputs: [{ name: '', type: 'bool' }], 176 | payable: false, 177 | stateMutability: 'nonpayable', 178 | type: 'function' 179 | }, 180 | { 181 | constant: false, 182 | inputs: [ 183 | { name: 'dst', type: 'address' }, 184 | { name: 'wad', type: 'uint256' } 185 | ], 186 | name: 'push', 187 | outputs: [], 188 | payable: false, 189 | stateMutability: 'nonpayable', 190 | type: 'function' 191 | }, 192 | { 193 | constant: false, 194 | inputs: [ 195 | { name: 'src', type: 'address' }, 196 | { name: 'dst', type: 'address' }, 197 | { name: 'wad', type: 'uint256' } 198 | ], 199 | name: 'move', 200 | outputs: [], 201 | payable: false, 202 | stateMutability: 'nonpayable', 203 | type: 'function' 204 | }, 205 | { 206 | constant: false, 207 | inputs: [], 208 | name: 'start', 209 | outputs: [], 210 | payable: false, 211 | stateMutability: 'nonpayable', 212 | type: 'function' 213 | }, 214 | { 215 | constant: true, 216 | inputs: [], 217 | name: 'authority', 218 | outputs: [{ name: '', type: 'address' }], 219 | payable: false, 220 | stateMutability: 'view', 221 | type: 'function' 222 | }, 223 | { 224 | constant: false, 225 | inputs: [{ name: 'guy', type: 'address' }], 226 | name: 'approve', 227 | outputs: [{ name: '', type: 'bool' }], 228 | payable: false, 229 | stateMutability: 'nonpayable', 230 | type: 'function' 231 | }, 232 | { 233 | constant: true, 234 | inputs: [ 235 | { name: 'src', type: 'address' }, 236 | { name: 'guy', type: 'address' } 237 | ], 238 | name: 'allowance', 239 | outputs: [{ name: '', type: 'uint256' }], 240 | payable: false, 241 | stateMutability: 'view', 242 | type: 'function' 243 | }, 244 | { 245 | constant: false, 246 | inputs: [ 247 | { name: 'src', type: 'address' }, 248 | { name: 'wad', type: 'uint256' } 249 | ], 250 | name: 'pull', 251 | outputs: [], 252 | payable: false, 253 | stateMutability: 'nonpayable', 254 | type: 'function' 255 | }, 256 | { 257 | inputs: [{ name: 'symbol_', type: 'bytes32' }], 258 | payable: false, 259 | stateMutability: 'nonpayable', 260 | type: 'constructor' 261 | }, 262 | { 263 | anonymous: false, 264 | inputs: [ 265 | { indexed: true, name: 'guy', type: 'address' }, 266 | { indexed: false, name: 'wad', type: 'uint256' } 267 | ], 268 | name: 'Mint', 269 | type: 'event' 270 | }, 271 | { 272 | anonymous: false, 273 | inputs: [ 274 | { indexed: true, name: 'guy', type: 'address' }, 275 | { indexed: false, name: 'wad', type: 'uint256' } 276 | ], 277 | name: 'Burn', 278 | type: 'event' 279 | }, 280 | { 281 | anonymous: false, 282 | inputs: [{ indexed: true, name: 'authority', type: 'address' }], 283 | name: 'LogSetAuthority', 284 | type: 'event' 285 | }, 286 | { 287 | anonymous: false, 288 | inputs: [{ indexed: true, name: 'owner', type: 'address' }], 289 | name: 'LogSetOwner', 290 | type: 'event' 291 | }, 292 | { 293 | anonymous: true, 294 | inputs: [ 295 | { indexed: true, name: 'sig', type: 'bytes4' }, 296 | { indexed: true, name: 'guy', type: 'address' }, 297 | { indexed: true, name: 'foo', type: 'bytes32' }, 298 | { indexed: true, name: 'bar', type: 'bytes32' }, 299 | { indexed: false, name: 'wad', type: 'uint256' }, 300 | { indexed: false, name: 'fax', type: 'bytes' } 301 | ], 302 | name: 'LogNote', 303 | type: 'event' 304 | }, 305 | { 306 | anonymous: false, 307 | inputs: [ 308 | { indexed: true, name: 'src', type: 'address' }, 309 | { indexed: true, name: 'guy', type: 'address' }, 310 | { indexed: false, name: 'wad', type: 'uint256' } 311 | ], 312 | name: 'Approval', 313 | type: 'event' 314 | }, 315 | { 316 | anonymous: false, 317 | inputs: [ 318 | { indexed: true, name: 'src', type: 'address' }, 319 | { indexed: true, name: 'dst', type: 'address' }, 320 | { indexed: false, name: 'wad', type: 'uint256' } 321 | ], 322 | name: 'Transfer', 323 | type: 'event' 324 | } 325 | ]; 326 | -------------------------------------------------------------------------------- /test/test-local/truffle-mint-dai/abi/erc20.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | constant: true, 4 | inputs: [], 5 | name: 'name', 6 | outputs: [{ name: '', type: 'bytes32' }], 7 | payable: false, 8 | stateMutability: 'view', 9 | type: 'function' 10 | }, 11 | { 12 | constant: false, 13 | inputs: [], 14 | name: 'stop', 15 | outputs: [], 16 | payable: false, 17 | stateMutability: 'nonpayable', 18 | type: 'function' 19 | }, 20 | { 21 | constant: false, 22 | inputs: [ 23 | { name: 'guy', type: 'address' }, 24 | { name: 'wad', type: 'uint256' } 25 | ], 26 | name: 'approve', 27 | outputs: [{ name: '', type: 'bool' }], 28 | payable: false, 29 | stateMutability: 'nonpayable', 30 | type: 'function' 31 | }, 32 | { 33 | constant: false, 34 | inputs: [{ name: 'owner_', type: 'address' }], 35 | name: 'setOwner', 36 | outputs: [], 37 | payable: false, 38 | stateMutability: 'nonpayable', 39 | type: 'function' 40 | }, 41 | { 42 | constant: true, 43 | inputs: [], 44 | name: 'totalSupply', 45 | outputs: [{ name: '', type: 'uint256' }], 46 | payable: false, 47 | stateMutability: 'view', 48 | type: 'function' 49 | }, 50 | { 51 | constant: false, 52 | inputs: [ 53 | { name: 'src', type: 'address' }, 54 | { name: 'dst', type: 'address' }, 55 | { name: 'wad', type: 'uint256' } 56 | ], 57 | name: 'transferFrom', 58 | outputs: [{ name: '', type: 'bool' }], 59 | payable: false, 60 | stateMutability: 'nonpayable', 61 | type: 'function' 62 | }, 63 | { 64 | constant: true, 65 | inputs: [], 66 | name: 'decimals', 67 | outputs: [{ name: '', type: 'uint256' }], 68 | payable: false, 69 | stateMutability: 'view', 70 | type: 'function' 71 | }, 72 | { 73 | constant: false, 74 | inputs: [ 75 | { name: 'guy', type: 'address' }, 76 | { name: 'wad', type: 'uint256' } 77 | ], 78 | name: 'mint', 79 | outputs: [], 80 | payable: false, 81 | stateMutability: 'nonpayable', 82 | type: 'function' 83 | }, 84 | { 85 | constant: false, 86 | inputs: [{ name: 'wad', type: 'uint256' }], 87 | name: 'burn', 88 | outputs: [], 89 | payable: false, 90 | stateMutability: 'nonpayable', 91 | type: 'function' 92 | }, 93 | { 94 | constant: false, 95 | inputs: [{ name: 'name_', type: 'bytes32' }], 96 | name: 'setName', 97 | outputs: [], 98 | payable: false, 99 | stateMutability: 'nonpayable', 100 | type: 'function' 101 | }, 102 | { 103 | constant: true, 104 | inputs: [{ name: 'src', type: 'address' }], 105 | name: 'balanceOf', 106 | outputs: [{ name: '', type: 'uint256' }], 107 | payable: false, 108 | stateMutability: 'view', 109 | type: 'function' 110 | }, 111 | { 112 | constant: true, 113 | inputs: [], 114 | name: 'stopped', 115 | outputs: [{ name: '', type: 'bool' }], 116 | payable: false, 117 | stateMutability: 'view', 118 | type: 'function' 119 | }, 120 | { 121 | constant: false, 122 | inputs: [{ name: 'authority_', type: 'address' }], 123 | name: 'setAuthority', 124 | outputs: [], 125 | payable: false, 126 | stateMutability: 'nonpayable', 127 | type: 'function' 128 | }, 129 | { 130 | constant: true, 131 | inputs: [], 132 | name: 'owner', 133 | outputs: [{ name: '', type: 'address' }], 134 | payable: false, 135 | stateMutability: 'view', 136 | type: 'function' 137 | }, 138 | { 139 | constant: true, 140 | inputs: [], 141 | name: 'symbol', 142 | outputs: [{ name: '', type: 'bytes32' }], 143 | payable: false, 144 | stateMutability: 'view', 145 | type: 'function' 146 | }, 147 | { 148 | constant: false, 149 | inputs: [ 150 | { name: 'guy', type: 'address' }, 151 | { name: 'wad', type: 'uint256' } 152 | ], 153 | name: 'burn', 154 | outputs: [], 155 | payable: false, 156 | stateMutability: 'nonpayable', 157 | type: 'function' 158 | }, 159 | { 160 | constant: false, 161 | inputs: [{ name: 'wad', type: 'uint256' }], 162 | name: 'mint', 163 | outputs: [], 164 | payable: false, 165 | stateMutability: 'nonpayable', 166 | type: 'function' 167 | }, 168 | { 169 | constant: false, 170 | inputs: [ 171 | { name: 'dst', type: 'address' }, 172 | { name: 'wad', type: 'uint256' } 173 | ], 174 | name: 'transfer', 175 | outputs: [{ name: '', type: 'bool' }], 176 | payable: false, 177 | stateMutability: 'nonpayable', 178 | type: 'function' 179 | }, 180 | { 181 | constant: false, 182 | inputs: [ 183 | { name: 'dst', type: 'address' }, 184 | { name: 'wad', type: 'uint256' } 185 | ], 186 | name: 'push', 187 | outputs: [], 188 | payable: false, 189 | stateMutability: 'nonpayable', 190 | type: 'function' 191 | }, 192 | { 193 | constant: false, 194 | inputs: [ 195 | { name: 'src', type: 'address' }, 196 | { name: 'dst', type: 'address' }, 197 | { name: 'wad', type: 'uint256' } 198 | ], 199 | name: 'move', 200 | outputs: [], 201 | payable: false, 202 | stateMutability: 'nonpayable', 203 | type: 'function' 204 | }, 205 | { 206 | constant: false, 207 | inputs: [], 208 | name: 'start', 209 | outputs: [], 210 | payable: false, 211 | stateMutability: 'nonpayable', 212 | type: 'function' 213 | }, 214 | { 215 | constant: true, 216 | inputs: [], 217 | name: 'authority', 218 | outputs: [{ name: '', type: 'address' }], 219 | payable: false, 220 | stateMutability: 'view', 221 | type: 'function' 222 | }, 223 | { 224 | constant: false, 225 | inputs: [{ name: 'guy', type: 'address' }], 226 | name: 'approve', 227 | outputs: [{ name: '', type: 'bool' }], 228 | payable: false, 229 | stateMutability: 'nonpayable', 230 | type: 'function' 231 | }, 232 | { 233 | constant: true, 234 | inputs: [ 235 | { name: 'src', type: 'address' }, 236 | { name: 'guy', type: 'address' } 237 | ], 238 | name: 'allowance', 239 | outputs: [{ name: '', type: 'uint256' }], 240 | payable: false, 241 | stateMutability: 'view', 242 | type: 'function' 243 | }, 244 | { 245 | constant: false, 246 | inputs: [ 247 | { name: 'src', type: 'address' }, 248 | { name: 'wad', type: 'uint256' } 249 | ], 250 | name: 'pull', 251 | outputs: [], 252 | payable: false, 253 | stateMutability: 'nonpayable', 254 | type: 'function' 255 | }, 256 | { 257 | inputs: [{ name: 'symbol_', type: 'bytes32' }], 258 | payable: false, 259 | stateMutability: 'nonpayable', 260 | type: 'constructor' 261 | }, 262 | { 263 | anonymous: false, 264 | inputs: [ 265 | { indexed: true, name: 'guy', type: 'address' }, 266 | { indexed: false, name: 'wad', type: 'uint256' } 267 | ], 268 | name: 'Mint', 269 | type: 'event' 270 | }, 271 | { 272 | anonymous: false, 273 | inputs: [ 274 | { indexed: true, name: 'guy', type: 'address' }, 275 | { indexed: false, name: 'wad', type: 'uint256' } 276 | ], 277 | name: 'Burn', 278 | type: 'event' 279 | }, 280 | { 281 | anonymous: false, 282 | inputs: [{ indexed: true, name: 'authority', type: 'address' }], 283 | name: 'LogSetAuthority', 284 | type: 'event' 285 | }, 286 | { 287 | anonymous: false, 288 | inputs: [{ indexed: true, name: 'owner', type: 'address' }], 289 | name: 'LogSetOwner', 290 | type: 'event' 291 | }, 292 | { 293 | anonymous: true, 294 | inputs: [ 295 | { indexed: true, name: 'sig', type: 'bytes4' }, 296 | { indexed: true, name: 'guy', type: 'address' }, 297 | { indexed: true, name: 'foo', type: 'bytes32' }, 298 | { indexed: true, name: 'bar', type: 'bytes32' }, 299 | { indexed: false, name: 'wad', type: 'uint256' }, 300 | { indexed: false, name: 'fax', type: 'bytes' } 301 | ], 302 | name: 'LogNote', 303 | type: 'event' 304 | }, 305 | { 306 | anonymous: false, 307 | inputs: [ 308 | { indexed: true, name: 'src', type: 'address' }, 309 | { indexed: true, name: 'guy', type: 'address' }, 310 | { indexed: false, name: 'wad', type: 'uint256' } 311 | ], 312 | name: 'Approval', 313 | type: 'event' 314 | }, 315 | { 316 | anonymous: false, 317 | inputs: [ 318 | { indexed: true, name: 'src', type: 'address' }, 319 | { indexed: true, name: 'dst', type: 'address' }, 320 | { indexed: false, name: 'wad', type: 'uint256' } 321 | ], 322 | name: 'Transfer', 323 | type: 'event' 324 | } 325 | ]; 326 | -------------------------------------------------------------------------------- /contracts/aave-v2/protocol/configuration/LendingPoolAddressesProvider.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; 5 | 6 | // Prettier ignore to prevent buidler flatter bug 7 | // prettier-ignore 8 | import {InitializableImmutableAdminUpgradeabilityProxy} from '../libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol'; 9 | 10 | import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; 11 | 12 | /** 13 | * @title LendingPoolAddressesProvider contract 14 | * @dev Main registry of addresses part of or connected to the protocol, including permissioned roles 15 | * - Acting also as factory of proxies and admin of those, so with right to change its implementations 16 | * - Owned by the Aave Governance 17 | * @author Aave 18 | **/ 19 | contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider { 20 | string private _marketId; 21 | mapping(bytes32 => address) private _addresses; 22 | 23 | bytes32 private constant LENDING_POOL = 'LENDING_POOL'; 24 | bytes32 private constant LENDING_POOL_CONFIGURATOR = 'LENDING_POOL_CONFIGURATOR'; 25 | bytes32 private constant POOL_ADMIN = 'POOL_ADMIN'; 26 | bytes32 private constant EMERGENCY_ADMIN = 'EMERGENCY_ADMIN'; 27 | bytes32 private constant LENDING_POOL_COLLATERAL_MANAGER = 'COLLATERAL_MANAGER'; 28 | bytes32 private constant PRICE_ORACLE = 'PRICE_ORACLE'; 29 | bytes32 private constant LENDING_RATE_ORACLE = 'LENDING_RATE_ORACLE'; 30 | 31 | constructor(string memory marketId) public { 32 | _setMarketId(marketId); 33 | } 34 | 35 | /** 36 | * @dev Returns the id of the Aave market to which this contracts points to 37 | * @return The market id 38 | **/ 39 | function getMarketId() external view override returns (string memory) { 40 | return _marketId; 41 | } 42 | 43 | /** 44 | * @dev Allows to set the market which this LendingPoolAddressesProvider represents 45 | * @param marketId The market id 46 | */ 47 | function setMarketId(string memory marketId) external override onlyOwner { 48 | _setMarketId(marketId); 49 | } 50 | 51 | /** 52 | * @dev General function to update the implementation of a proxy registered with 53 | * certain `id`. If there is no proxy registered, it will instantiate one and 54 | * set as implementation the `implementationAddress` 55 | * IMPORTANT Use this function carefully, only for ids that don't have an explicit 56 | * setter function, in order to avoid unexpected consequences 57 | * @param id The id 58 | * @param implementationAddress The address of the new implementation 59 | */ 60 | function setAddressAsProxy(bytes32 id, address implementationAddress) 61 | external 62 | override 63 | onlyOwner 64 | { 65 | _updateImpl(id, implementationAddress); 66 | emit AddressSet(id, implementationAddress, true); 67 | } 68 | 69 | /** 70 | * @dev Sets an address for an id replacing the address saved in the addresses map 71 | * IMPORTANT Use this function carefully, as it will do a hard replacement 72 | * @param id The id 73 | * @param newAddress The address to set 74 | */ 75 | function setAddress(bytes32 id, address newAddress) external override onlyOwner { 76 | _addresses[id] = newAddress; 77 | emit AddressSet(id, newAddress, false); 78 | } 79 | 80 | /** 81 | * @dev Returns an address by id 82 | * @return The address 83 | */ 84 | function getAddress(bytes32 id) public view override returns (address) { 85 | return _addresses[id]; 86 | } 87 | 88 | /** 89 | * @dev Returns the address of the LendingPool proxy 90 | * @return The LendingPool proxy address 91 | **/ 92 | function getLendingPool() external view override returns (address) { 93 | return getAddress(LENDING_POOL); 94 | } 95 | 96 | /** 97 | * @dev Updates the implementation of the LendingPool, or creates the proxy 98 | * setting the new `pool` implementation on the first time calling it 99 | * @param pool The new LendingPool implementation 100 | **/ 101 | function setLendingPoolImpl(address pool) external override onlyOwner { 102 | _updateImpl(LENDING_POOL, pool); 103 | emit LendingPoolUpdated(pool); 104 | } 105 | 106 | /** 107 | * @dev Returns the address of the LendingPoolConfigurator proxy 108 | * @return The LendingPoolConfigurator proxy address 109 | **/ 110 | function getLendingPoolConfigurator() external view override returns (address) { 111 | return getAddress(LENDING_POOL_CONFIGURATOR); 112 | } 113 | 114 | /** 115 | * @dev Updates the implementation of the LendingPoolConfigurator, or creates the proxy 116 | * setting the new `configurator` implementation on the first time calling it 117 | * @param configurator The new LendingPoolConfigurator implementation 118 | **/ 119 | function setLendingPoolConfiguratorImpl(address configurator) external override onlyOwner { 120 | _updateImpl(LENDING_POOL_CONFIGURATOR, configurator); 121 | emit LendingPoolConfiguratorUpdated(configurator); 122 | } 123 | 124 | /** 125 | * @dev Returns the address of the LendingPoolCollateralManager. Since the manager is used 126 | * through delegateCall within the LendingPool contract, the proxy contract pattern does not work properly hence 127 | * the addresses are changed directly 128 | * @return The address of the LendingPoolCollateralManager 129 | **/ 130 | 131 | function getLendingPoolCollateralManager() external view override returns (address) { 132 | return getAddress(LENDING_POOL_COLLATERAL_MANAGER); 133 | } 134 | 135 | /** 136 | * @dev Updates the address of the LendingPoolCollateralManager 137 | * @param manager The new LendingPoolCollateralManager address 138 | **/ 139 | function setLendingPoolCollateralManager(address manager) external override onlyOwner { 140 | _addresses[LENDING_POOL_COLLATERAL_MANAGER] = manager; 141 | emit LendingPoolCollateralManagerUpdated(manager); 142 | } 143 | 144 | /** 145 | * @dev The functions below are getters/setters of addresses that are outside the context 146 | * of the protocol hence the upgradable proxy pattern is not used 147 | **/ 148 | 149 | function getPoolAdmin() external view override returns (address) { 150 | return getAddress(POOL_ADMIN); 151 | } 152 | 153 | function setPoolAdmin(address admin) external override onlyOwner { 154 | _addresses[POOL_ADMIN] = admin; 155 | emit ConfigurationAdminUpdated(admin); 156 | } 157 | 158 | function getEmergencyAdmin() external view override returns (address) { 159 | return getAddress(EMERGENCY_ADMIN); 160 | } 161 | 162 | function setEmergencyAdmin(address emergencyAdmin) external override onlyOwner { 163 | _addresses[EMERGENCY_ADMIN] = emergencyAdmin; 164 | emit EmergencyAdminUpdated(emergencyAdmin); 165 | } 166 | 167 | function getPriceOracle() external view override returns (address) { 168 | return getAddress(PRICE_ORACLE); 169 | } 170 | 171 | function setPriceOracle(address priceOracle) external override onlyOwner { 172 | _addresses[PRICE_ORACLE] = priceOracle; 173 | emit PriceOracleUpdated(priceOracle); 174 | } 175 | 176 | function getLendingRateOracle() external view override returns (address) { 177 | return getAddress(LENDING_RATE_ORACLE); 178 | } 179 | 180 | function setLendingRateOracle(address lendingRateOracle) external override onlyOwner { 181 | _addresses[LENDING_RATE_ORACLE] = lendingRateOracle; 182 | emit LendingRateOracleUpdated(lendingRateOracle); 183 | } 184 | 185 | /** 186 | * @dev Internal function to update the implementation of a specific proxied component of the protocol 187 | * - If there is no proxy registered in the given `id`, it creates the proxy setting `newAdress` 188 | * as implementation and calls the initialize() function on the proxy 189 | * - If there is already a proxy registered, it just updates the implementation to `newAddress` and 190 | * calls the initialize() function via upgradeToAndCall() in the proxy 191 | * @param id The id of the proxy to be updated 192 | * @param newAddress The address of the new implementation 193 | **/ 194 | function _updateImpl(bytes32 id, address newAddress) internal { 195 | address payable proxyAddress = payable(_addresses[id]); 196 | 197 | InitializableImmutableAdminUpgradeabilityProxy proxy = 198 | InitializableImmutableAdminUpgradeabilityProxy(proxyAddress); 199 | bytes memory params = abi.encodeWithSignature('initialize(address)', address(this)); 200 | 201 | if (proxyAddress == address(0)) { 202 | proxy = new InitializableImmutableAdminUpgradeabilityProxy(address(this)); 203 | proxy.initialize(newAddress, params); 204 | _addresses[id] = address(proxy); 205 | emit ProxyCreated(id, address(proxy)); 206 | } else { 207 | proxy.upgradeToAndCall(newAddress, params); 208 | } 209 | } 210 | 211 | function _setMarketId(string memory marketId) internal { 212 | _marketId = marketId; 213 | emit MarketIdSet(marketId); 214 | } 215 | } 216 | --------------------------------------------------------------------------------