├── .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 | 
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 |
--------------------------------------------------------------------------------