├── README.md ├── LendingPool.sol ├── .gitignore ├── BondingCurve.sol ├── LendingCurve.sol ├── FlashForwardLoan.sol ├── LendingVault.sol ├── Libraries.sol ├── LICENSE └── Interfaces.sol /README.md: -------------------------------------------------------------------------------- 1 | # PromiseNet 2 | Flash Loan Aggregation and Credit Delegation Distribution over a Bonding Curve 3 | -------------------------------------------------------------------------------- /LendingPool.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 4 | import { LendingPoolAddressesProvider } from "../interfaces/LendingPoolAddressesProvider.sol"; 5 | 6 | contract LendingPool { 7 | 8 | // Lending Providor contract 9 | // Acccess a specific lending pool via the provider 10 | LendingPoolAddressesProvider provider = LendingPoolAddressesProvider(address(0x24a42fD28C976A61Df5D00D0599C34c4f90748c8)); // Mainnet Address 11 | LendingPool lendingPool = LendingPool(provider.getLendingPool()); 12 | 13 | 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /BondingCurve.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | 3 | 4 | import "openzeppelin-eth/contracts/math/SafeMath.sol"; 5 | import "openzeppelin-eth/contracts/token/ERC20/ERC20.sol"; 6 | import "openzeppelin-eth/contracts/token/ERC20/ERC20Detailed.sol"; 7 | import "zos-lib/contracts/Initializable.sol"; 8 | 9 | contract BondingCurve is Initializable, ERC20, ERC20Detailed { 10 | 11 | using SafeMath for uint256; 12 | 13 | uint256 public reserve; 14 | 15 | event CurveBuy(uint256 amount, uint256 paid, uint256 indexed when); 16 | event CurveSell(uint256 amount, uint256 rewarded, uint256 indexed when); 17 | 18 | function initialize(string memory name, string memory symbol, uint8 decimals) public initializer { 19 | ERC20Detailed.initialize(name, symbol, decimals); 20 | } 21 | 22 | /** 23 | * Curve function interfaces 24 | */ 25 | function calculatePurchaseReturn(uint256 tokens) public view returns (uint256 thePrice); 26 | function calculateSaleReturn(uint256 tokens) public view returns (uint256 theReward); 27 | 28 | 29 | function buy(uint256 tokens) public payable { 30 | require(tokens > 0, "Must request non-zero amount of tokens."); 31 | 32 | uint256 paid = calculatePurchaseReturn(tokens); 33 | require( 34 | msg.value >= paid, 35 | "Did not send enough ether to buy!" 36 | ); 37 | 38 | reserve = reserve.add(paid); 39 | _mint(msg.sender, tokens); 40 | //extra funds handling 41 | if (msg.value > paid) { 42 | msg.sender.transfer(msg.value.sub(paid)); 43 | } 44 | 45 | emit CurveBuy(tokens, paid, now); 46 | } 47 | 48 | function sell(uint256 tokens) 49 | public returns (uint256 rewarded) 50 | { 51 | require(tokens > 0, "Must spend non-zero amount of tokens."); 52 | require( 53 | balanceOf(msg.sender) >= tokens, 54 | "Sender does not have enough tokens to spend." 55 | ); 56 | 57 | rewarded = calculateSaleReturn(tokens); 58 | reserve = reserve.sub(rewarded); 59 | _burn(msg.sender, tokens); 60 | msg.sender.transfer(rewarded); 61 | 62 | emit CurveSell(tokens, rewarded, now); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /LendingCurve.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | 3 | 4 | import "zos-lib/contracts/Initializable.sol"; 5 | import "./BondingCurve.sol"; 6 | 7 | contract LendingCurve is Initializable, BondingCurve { 8 | 9 | address payable wallet; 10 | 11 | // Desired Curve: Linear Progression W/ % Buy/Sell Delta 12 | // Ex: Sell is always 90% of buy price. 13 | // https://www.desmos.com/calculator/9ierxx6kjw 14 | uint256 slopeNumerator; 15 | uint256 slopeDenominator; 16 | uint256 sellPercentage; // ex: 90 == 90% of buy price 17 | 18 | event Payout(uint256 payout, uint256 indexed timestamp); 19 | 20 | function initialize( 21 | string memory name, 22 | string memory symbol, 23 | uint8 decimals, 24 | address payable _wallet, 25 | uint256 _slopeNumerator, 26 | uint256 _slopeDenominator, 27 | uint256 _sellPercentage 28 | ) public initializer { 29 | require( 30 | _sellPercentage < 100 && _sellPercentage != 0, 31 | "Percentage must be between 0 & 100" 32 | ); 33 | 34 | BondingCurve.initialize(name, symbol, decimals); 35 | wallet = _wallet; 36 | slopeNumerator = _slopeNumerator; 37 | slopeDenominator = _slopeDenominator; 38 | sellPercentage = _sellPercentage; 39 | } 40 | 41 | function buyIntegral(uint256 x) 42 | internal view returns (uint256) 43 | { 44 | return (slopeNumerator * x * x) / (2 * slopeDenominator); 45 | } 46 | 47 | function sellIntegral(uint256 x) 48 | internal view returns (uint256) 49 | { 50 | return (slopeNumerator * x * x * sellPercentage) / (200 * slopeDenominator); 51 | } 52 | 53 | function spread(uint256 toX) 54 | public view returns (uint256) 55 | { 56 | uint256 buy = buyIntegral(toX); 57 | uint256 sell = sellIntegral(toX); 58 | return buy.sub(sell); 59 | } 60 | 61 | /// Overwrite 62 | function buy(uint256 tokens) public payable { 63 | uint256 spreadBefore = spread(totalSupply()); 64 | super.buy(tokens); 65 | 66 | uint256 spreadAfter = spread(totalSupply()); 67 | 68 | uint256 spreadPayout = spreadAfter.sub(spreadBefore); 69 | reserve = reserve.sub(spreadPayout); 70 | wallet.transfer(spreadPayout); 71 | 72 | emit Payout(spreadPayout, now); 73 | } 74 | 75 | function calculatePurchaseReturn(uint256 tokens) 76 | public view returns (uint256) 77 | { 78 | return buyIntegral( 79 | totalSupply().add(tokens) 80 | ).sub(reserve); 81 | } 82 | 83 | function calculateSaleReturn(uint256 tokens) 84 | public view returns (uint256) 85 | { 86 | return reserve.sub( 87 | sellIntegral( 88 | totalSupply().sub(tokens) 89 | )); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /FlashForwardLoan.sol: -------------------------------------------------------------------------------- 1 | 2 | // SPDX-License-Identifier: MIT 3 | pragma solidity >=0.6.2 <0.7.0; 4 | pragma experimental ABIEncoderV2; 5 | 6 | import "@openzeppelin/contracts/utils/SafeCast.sol"; 7 | import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; 8 | import "./interfaces/IZkSync.sol"; 9 | import "./interfaces/IUSDC.sol"; 10 | import "./BasicMetaTransaction.sol"; 11 | 12 | import { FlashLoanReceiverBase } from "FlashLoanReceiverBase.sol"; 13 | import { ILendingPool, ILendingPoolAddressesProvider, IERC20 } from "Interfaces.sol"; 14 | import { SafeMath } from "Libraries.sol"; 15 | 16 | /** 17 | !!! 18 | Never keep funds permanently on your FlashLoanReceiverBase contract as they could be 19 | exposed to a 'griefing' attack, where the stored funds are used by an attacker. 20 | !!! 21 | */ 22 | contract FlashForwardLoan is FlashLoanReceiverBase, BasicMetaTransaction { 23 | using SafeMath for uint256; 24 | 25 | constructor(ILendingPoolAddressesProvider _addressProvider) FlashLoanReceiverBase(_addressProvider) public {} 26 | 27 | 28 | using SafeERC20 for IERC20; 29 | using SafeERC20 for IUSDC; 30 | 31 | IZkSync internal _zkSync; 32 | IUSDC private _usdc; 33 | 34 | constructor( 35 | IZkSync zkSync, 36 | IUSDC usdc, 37 | uint256 chainId 38 | ) public BasicMetaTransaction(chainId) { 39 | _zkSync = zkSync; 40 | _usdc = usdc; 41 | _usdc.safeApprove(address(_zkSync), uint256(-1)); 42 | } 43 | 44 | receive() external payable {} 45 | 46 | function deposit( 47 | address from, 48 | address to, 49 | uint256 value, 50 | uint256 validAfter, 51 | uint256 validBefore, 52 | bytes32 nonce, 53 | uint8 v, 54 | bytes32 r, 55 | bytes32 s 56 | ) external { 57 | require(value < 2**104, "Amount doesn't fit in 104 bits"); 58 | require(to == address(this), "Recipient is not this contract"); 59 | 60 | _usdc.transferWithAuthorization( 61 | from, 62 | to, 63 | value, 64 | validAfter, 65 | validBefore, 66 | nonce, 67 | v, 68 | r, 69 | s 70 | ); 71 | 72 | _zkSync.depositERC20(address(_usdc), uint104(value), from); 73 | } 74 | 75 | function claim() external { 76 | address user = _msgSender(); 77 | _usdc.safeTransfer(user, 100 * (10**6)); 78 | } 79 | } 80 | 81 | /** 82 | This function is called after your contract has received the flash loaned amount 83 | */ 84 | function executeOperation( 85 | address[] calldata assets, 86 | uint256[] calldata amounts, 87 | uint256[] calldata premiums, 88 | address initiator, 89 | bytes calldata params 90 | ) 91 | external 92 | override 93 | returns (bool) 94 | { 95 | 96 | // 97 | // This contract now has the funds requested. 98 | // Your logic goes here. 99 | // 100 | 101 | // At the end of your logic above, this contract owes 102 | // the flashloaned amounts + premiums. 103 | // Therefore ensure your contract has enough to repay 104 | // these amounts. 105 | 106 | // Approve the LendingPool contract allowance to *pull* the owed amount 107 | for (uint i = 0; i < assets.length; i++) { 108 | uint amountOwing = amounts[i].add(premiums[i]); 109 | IERC20(assets[i]).approve(address(LENDING_POOL), amountOwing); 110 | } 111 | 112 | return true; 113 | } 114 | 115 | function myFlashLoanCall() public { 116 | address receiverAddress = address(this); 117 | 118 | address[] memory assets = new address[](7); 119 | assets[0] = address(0xB597cd8D3217ea6477232F9217fa70837ff667Af); // Kovan AAVE 120 | assets[1] = address(0x2d12186Fbb9f9a8C28B3FfdD4c42920f8539D738); // Kovan BAT 121 | assets[2] = address(0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD); // Kovan DAI 122 | assets[3] = address(0x075A36BA8846C6B6F53644fDd3bf17E5151789DC); // Kovan UNI 123 | assets[4] = address(0xb7c325266ec274fEb1354021D27FA3E3379D840d); // Kovan YFI 124 | assets[5] = address(0xAD5ce863aE3E4E9394Ab43d4ba0D80f419F61789); // Kovan LINK 125 | assets[6] = address(0x7FDb81B0b8a010dd4FFc57C3fecbf145BA8Bd947); // Kovan SNX 126 | 127 | uint256[] memory amounts = new uint256[](7); 128 | amounts[0] = 1 ether; 129 | amounts[1] = 1 ether; 130 | amounts[2] = 1 ether; 131 | amounts[3] = 1 ether; 132 | amounts[4] = 1 ether; 133 | amounts[5] = 1 ether; 134 | amounts[6] = 1 ether; 135 | 136 | // 0 = no debt, 1 = stable, 2 = variable 137 | uint256[] memory modes = new uint256[](7); 138 | modes[0] = 0; 139 | modes[1] = 0; 140 | modes[2] = 0; 141 | modes[3] = 0; 142 | modes[4] = 0; 143 | modes[5] = 0; 144 | modes[6] = 0; 145 | 146 | address onBehalfOf = address(this); 147 | bytes memory params = ""; 148 | uint16 referralCode = 0; 149 | 150 | LENDING_POOL.flashLoan( 151 | receiverAddress, 152 | assets, 153 | amounts, 154 | modes, 155 | onBehalfOf, 156 | params, 157 | referralCode 158 | ); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /LendingVault.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | 4 | import { IERC20, IERC721, ILendingPool, IProtocolDataProvider, IStableDebtToken } from './Interfaces.sol'; 5 | import { SafeERC20, SafeMath } from './Libraries.sol'; 6 | 7 | /** 8 | * This is a proof of concept starter contract, showing how uncollaterised loans are possible 9 | * using Aave v2 credit delegation. 10 | * This example supports stable interest rate borrows. 11 | * It is not production ready (!). User permissions and user accounting of loans should be implemented. 12 | * See @dev comments 13 | */ 14 | 15 | contract MyV2CreditDelegation { 16 | using SafeERC20 for IERC20; 17 | using SafeMath for uint256; 18 | 19 | ILendingPool constant lendingPool = ILendingPool(address(0x9FE532197ad76c5a68961439604C037EB79681F0)); // Kovan 20 | IProtocolDataProvider constant dataProvider = IProtocolDataProvider(address(0x744C1aaA95232EeF8A9994C4E0b3a89659D9AB79)); // Kovan 21 | 22 | address owner; 23 | 24 | struct Term { 25 | uint256 limit; // Borrowing limit in wei 26 | uint256 rateMultiplier; // Interest rate on top of Aave set rate 27 | } 28 | 29 | struct Loan { 30 | uint256 rateMultiplier; 31 | bool active; 32 | uint256 principalBalance; 33 | } 34 | 35 | // Track balances by asset address 36 | mapping (address => mapping (address => uint256)) public balances; 37 | 38 | // Map NFT addresses to limits 39 | mapping ( address => Term ) public terms; 40 | 41 | mapping ( address => mapping (uint256 => bool)) public burnedApprovals; 42 | 43 | // Track addresses with active loans. Same address cannot have multiple lines open per asset with different terms 44 | mapping ( address => mapping (address => Loan )) public loans; 45 | 46 | constructor () public { 47 | owner = msg.sender; 48 | terms[0x0000000000000000000000000000000000000001] = Term({limit: 1 ether, rateMultiplier: 5}); //Placeholder - limit arg should be an NFT address 49 | terms[0x0000000000000000000000000000000000000002] = Term({limit: 5 ether, rateMultiplier: 3}); // Placeholder - limit arg should be an NFT address 50 | } 51 | 52 | /** 53 | * Deposits collateral into the Aave, to enable credit delegation 54 | * This would be called by the delegator. 55 | * @param asset The asset to be deposited as collateral 56 | * @param amount The amount to be deposited as collateral 57 | * User must have approved this contract 58 | * 59 | */ 60 | function depositCollateral(address asset, uint256 amount) public { 61 | IERC20(asset).safeTransferFrom(msg.sender, address(this), amount); 62 | IERC20(asset).safeApprove(address(lendingPool), amount); 63 | // aTokens go to this contract 64 | lendingPool.deposit(asset, amount, address(this), 0); 65 | // Track how much collateral the investor has supplied 66 | balances[asset][msg.sender] += amount; 67 | // Track how much total collateral of this asset type has been supplied 68 | balances[asset][address(this)] += amount; 69 | } 70 | 71 | /** 72 | * Checks if sender is approved, and if so opens a credit delegation line 73 | * @param approvalNFT The NFT address representing the creditworthiness 74 | * @param tokenId The NFT ID of the approval being used 75 | * @param asset The asset they are allowed to borrow 76 | * 77 | * Allows a borrower holding a valid NFT to borrow at the rate set in the constructor 78 | */ 79 | function requestCredit(address approvalNFT, uint256 tokenId, address asset) public { 80 | require(IERC721(approvalNFT).ownerOf(tokenId) == msg.sender); 81 | burnedApprovals[approvalNFT][tokenId] = true; 82 | 83 | (, address stableDebtTokenAddress,) = dataProvider.getReserveTokensAddresses(asset); 84 | IStableDebtToken(stableDebtTokenAddress).approveDelegation(msg.sender, terms[approvalNFT].limit); 85 | 86 | // Note that we are assuming the borrower withdraws the full amount 87 | loans[stableDebtTokenAddress][msg.sender] = Loan({rateMultiplier: terms[approvalNFT].rateMultiplier, active: true, principalBalance: terms[approvalNFT].limit}); 88 | // After this step the borrower can call borrow with this contract as the onBehalfOf 89 | } 90 | 91 | /** 92 | * Repay an uncollaterised loan 93 | * @param amount The amount to repay 94 | * @param asset The asset to be repaid 95 | * 96 | * User calling this function must have approved this contract with an allowance to transfer the tokens 97 | */ 98 | function repayBorrower(uint256 amount, address asset) public { 99 | IERC20(asset).safeTransferFrom(msg.sender, address(this), amount); 100 | IERC20(asset).safeApprove(address(lendingPool), amount); 101 | 102 | // Calculate the additional interest margin and extract that from the repayment amount 103 | (, address stableDebtTokenAddress,) = dataProvider.getReserveTokensAddresses(asset); 104 | uint256 principalBalance = IStableDebtToken(stableDebtTokenAddress).principalBalanceOf(msg.sender); 105 | uint256 baseBalance = IStableDebtToken(stableDebtTokenAddress).balanceOf(msg.sender); 106 | 107 | require(principalBalance == loans[stableDebtTokenAddress][msg.sender].principalBalance); 108 | 109 | // This will throw if accounting gets corrupted and lending pool balance is lower than principal balance 110 | uint256 baseInterest = baseBalance.sub(loans[stableDebtTokenAddress][msg.sender].principalBalance); 111 | 112 | uint256 premiumInterest = baseInterest.mul(loans[stableDebtTokenAddress][msg.sender].rateMultiplier); 113 | 114 | // Extract premium interest and distribute to pool 115 | uint256 repaymentAmount = amount.sub(premiumInterest); 116 | 117 | // The remaining amount stays in this contract gets deposited into the lending pool 118 | IERC20(asset).safeApprove(address(lendingPool), premiumInterest); 119 | // aTokens go to this contract 120 | lendingPool.deposit(asset, premiumInterest, address(this), 0); 121 | 122 | 123 | // Repaying has to be done at the aave rate 124 | // Repay uses the delegator's address for onBehalfOf 125 | lendingPool.repay(asset, repaymentAmount, 1, address(this)); 126 | uint256 newPrincipalBalance = IStableDebtToken(stableDebtTokenAddress).principalBalanceOf(msg.sender); 127 | loans[stableDebtTokenAddress][msg.sender].principalBalance = newPrincipalBalance; 128 | } 129 | 130 | /** 131 | * Check balance of the borrower 132 | * @param account The address of the borrower 133 | * @param asset The asset to be repaid 134 | * 135 | */ 136 | function balanceOf(address account, address asset) public view returns (uint256) { 137 | // Calculate the additional interest margin and extract that from the repayment amount 138 | (, address stableDebtTokenAddress,) = dataProvider.getReserveTokensAddresses(asset); 139 | uint256 principalBalance = IStableDebtToken(stableDebtTokenAddress).principalBalanceOf(account); 140 | uint256 baseBalance = IStableDebtToken(stableDebtTokenAddress).balanceOf(account); 141 | 142 | require(principalBalance == loans[stableDebtTokenAddress][account].principalBalance); 143 | 144 | // This will throw if accounting gets corrupted and lending pool balance is lower than principal balance 145 | uint256 baseInterest = baseBalance.sub(loans[stableDebtTokenAddress][account].principalBalance); 146 | 147 | uint256 premiumInterest = baseInterest.mul(loans[stableDebtTokenAddress][account].rateMultiplier); 148 | 149 | uint256 balance = baseBalance.add(premiumInterest); 150 | 151 | return balance; 152 | } 153 | 154 | 155 | /** 156 | * Withdraw all of a collateral as the underlying asset, if no outstanding loans delegated 157 | * @param asset The underlying asset to withdraw 158 | * 159 | * Add permissions to this call, e.g. only the owner should be able to withdraw the collateral! 160 | */ 161 | function withdrawCollateral(address asset) public { 162 | (address aTokenAddress,,) = dataProvider.getReserveTokensAddresses(asset); 163 | uint256 assetBalance = IERC20(aTokenAddress).balanceOf(address(this)); 164 | uint256 senderCollateral = balances[asset][msg.sender]; 165 | uint256 totalCollateral = balances[asset][address(this)]; 166 | // Get the ratio of the collateral to evenly distribute rewards 167 | uint256 senderBalanceRatio = senderCollateral.div(totalCollateral); 168 | uint256 senderBalance = assetBalance.mul(senderBalanceRatio); 169 | balances[asset][msg.sender] -= senderCollateral; 170 | balances[asset][address(this)] -= senderCollateral; 171 | lendingPool.withdraw(asset, senderBalance, msg.sender); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /Libraries.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | pragma experimental ABIEncoderV2; 4 | 5 | import { IERC20 } from "./Interfaces.sol"; 6 | 7 | library DataTypes { 8 | // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. 9 | struct ReserveData { 10 | //stores the reserve configuration 11 | ReserveConfigurationMap configuration; 12 | //the liquidity index. Expressed in ray 13 | uint128 liquidityIndex; 14 | //variable borrow index. Expressed in ray 15 | uint128 variableBorrowIndex; 16 | //the current supply rate. Expressed in ray 17 | uint128 currentLiquidityRate; 18 | //the current variable borrow rate. Expressed in ray 19 | uint128 currentVariableBorrowRate; 20 | //the current stable borrow rate. Expressed in ray 21 | uint128 currentStableBorrowRate; 22 | uint40 lastUpdateTimestamp; 23 | //tokens addresses 24 | address aTokenAddress; 25 | address stableDebtTokenAddress; 26 | address variableDebtTokenAddress; 27 | //address of the interest rate strategy 28 | address interestRateStrategyAddress; 29 | //the id of the reserve. Represents the position in the list of the active reserves 30 | uint8 id; 31 | } 32 | 33 | struct ReserveConfigurationMap { 34 | //bit 0-15: LTV 35 | //bit 16-31: Liq. threshold 36 | //bit 32-47: Liq. bonus 37 | //bit 48-55: Decimals 38 | //bit 56: Reserve is active 39 | //bit 57: reserve is frozen 40 | //bit 58: borrowing is enabled 41 | //bit 59: stable rate borrowing enabled 42 | //bit 60-63: reserved 43 | //bit 64-79: reserve factor 44 | uint256 data; 45 | } 46 | 47 | struct UserConfigurationMap { 48 | uint256 data; 49 | } 50 | 51 | enum InterestRateMode {NONE, STABLE, VARIABLE} 52 | } 53 | 54 | library SafeMath { 55 | /** 56 | * @dev Returns the addition of two unsigned integers, reverting on 57 | * overflow. 58 | * 59 | * Counterpart to Solidity's `+` operator. 60 | * 61 | * Requirements: 62 | * - Addition cannot overflow. 63 | */ 64 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 65 | uint256 c = a + b; 66 | require(c >= a, 'SafeMath: addition overflow'); 67 | 68 | return c; 69 | } 70 | 71 | /** 72 | * @dev Returns the subtraction of two unsigned integers, reverting on 73 | * overflow (when the result is negative). 74 | * 75 | * Counterpart to Solidity's `-` operator. 76 | * 77 | * Requirements: 78 | * - Subtraction cannot overflow. 79 | */ 80 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 81 | return sub(a, b, 'SafeMath: subtraction overflow'); 82 | } 83 | 84 | /** 85 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 86 | * overflow (when the result is negative). 87 | * 88 | * Counterpart to Solidity's `-` operator. 89 | * 90 | * Requirements: 91 | * - Subtraction cannot overflow. 92 | */ 93 | function sub( 94 | uint256 a, 95 | uint256 b, 96 | string memory errorMessage 97 | ) internal pure returns (uint256) { 98 | require(b <= a, errorMessage); 99 | uint256 c = a - b; 100 | 101 | return c; 102 | } 103 | 104 | /** 105 | * @dev Returns the multiplication of two unsigned integers, reverting on 106 | * overflow. 107 | * 108 | * Counterpart to Solidity's `*` operator. 109 | * 110 | * Requirements: 111 | * - Multiplication cannot overflow. 112 | */ 113 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 114 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 115 | // benefit is lost if 'b' is also tested. 116 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 117 | if (a == 0) { 118 | return 0; 119 | } 120 | 121 | uint256 c = a * b; 122 | require(c / a == b, 'SafeMath: multiplication overflow'); 123 | 124 | return c; 125 | } 126 | 127 | /** 128 | * @dev Returns the integer division of two unsigned integers. Reverts on 129 | * division by zero. The result is rounded towards zero. 130 | * 131 | * Counterpart to Solidity's `/` operator. Note: this function uses a 132 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 133 | * uses an invalid opcode to revert (consuming all remaining gas). 134 | * 135 | * Requirements: 136 | * - The divisor cannot be zero. 137 | */ 138 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 139 | return div(a, b, 'SafeMath: division by zero'); 140 | } 141 | 142 | /** 143 | * @dev Returns the integer division of two unsigned integers. Reverts with custom message on 144 | * division by zero. The result is rounded towards zero. 145 | * 146 | * Counterpart to Solidity's `/` operator. Note: this function uses a 147 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 148 | * uses an invalid opcode to revert (consuming all remaining gas). 149 | * 150 | * Requirements: 151 | * - The divisor cannot be zero. 152 | */ 153 | function div( 154 | uint256 a, 155 | uint256 b, 156 | string memory errorMessage 157 | ) internal pure returns (uint256) { 158 | // Solidity only automatically asserts when dividing by 0 159 | require(b > 0, errorMessage); 160 | uint256 c = a / b; 161 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 162 | 163 | return c; 164 | } 165 | 166 | /** 167 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 168 | * Reverts when dividing by zero. 169 | * 170 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 171 | * opcode (which leaves remaining gas untouched) while Solidity uses an 172 | * invalid opcode to revert (consuming all remaining gas). 173 | * 174 | * Requirements: 175 | * - The divisor cannot be zero. 176 | */ 177 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 178 | return mod(a, b, 'SafeMath: modulo by zero'); 179 | } 180 | 181 | /** 182 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 183 | * Reverts with custom message when dividing by zero. 184 | * 185 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 186 | * opcode (which leaves remaining gas untouched) while Solidity uses an 187 | * invalid opcode to revert (consuming all remaining gas). 188 | * 189 | * Requirements: 190 | * - The divisor cannot be zero. 191 | */ 192 | function mod( 193 | uint256 a, 194 | uint256 b, 195 | string memory errorMessage 196 | ) internal pure returns (uint256) { 197 | require(b != 0, errorMessage); 198 | return a % b; 199 | } 200 | } 201 | 202 | library Address { 203 | /** 204 | * @dev Returns true if `account` is a contract. 205 | * 206 | * [IMPORTANT] 207 | * ==== 208 | * It is unsafe to assume that an address for which this function returns 209 | * false is an externally-owned account (EOA) and not a contract. 210 | * 211 | * Among others, `isContract` will return false for the following 212 | * types of addresses: 213 | * 214 | * - an externally-owned account 215 | * - a contract in construction 216 | * - an address where a contract will be created 217 | * - an address where a contract lived, but was destroyed 218 | * ==== 219 | */ 220 | function isContract(address account) internal view returns (bool) { 221 | // According to EIP-1052, 0x0 is the value returned for not-yet created accounts 222 | // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned 223 | // for accounts without code, i.e. `keccak256('')` 224 | bytes32 codehash; 225 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 226 | // solhint-disable-next-line no-inline-assembly 227 | assembly { 228 | codehash := extcodehash(account) 229 | } 230 | return (codehash != accountHash && codehash != 0x0); 231 | } 232 | 233 | /** 234 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 235 | * `recipient`, forwarding all available gas and reverting on errors. 236 | * 237 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 238 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 239 | * imposed by `transfer`, making them unable to receive funds via 240 | * `transfer`. {sendValue} removes this limitation. 241 | * 242 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 243 | * 244 | * IMPORTANT: because control is transferred to `recipient`, care must be 245 | * taken to not create reentrancy vulnerabilities. Consider using 246 | * {ReentrancyGuard} or the 247 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 248 | */ 249 | function sendValue(address payable recipient, uint256 amount) internal { 250 | require(address(this).balance >= amount, 'Address: insufficient balance'); 251 | 252 | // solhint-disable-next-line avoid-low-level-calls, avoid-call-value 253 | (bool success, ) = recipient.call{value: amount}(''); 254 | require(success, 'Address: unable to send value, recipient may have reverted'); 255 | } 256 | } 257 | 258 | /** 259 | * @title SafeERC20 260 | * @dev Wrappers around ERC20 operations that throw on failure (when the token 261 | * contract returns false). Tokens that return no value (and instead revert or 262 | * throw on failure) are also supported, non-reverting calls are assumed to be 263 | * successful. 264 | * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, 265 | * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. 266 | */ 267 | library SafeERC20 { 268 | using SafeMath for uint256; 269 | using Address for address; 270 | 271 | function safeTransfer( 272 | IERC20 token, 273 | address to, 274 | uint256 value 275 | ) internal { 276 | callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 277 | } 278 | 279 | function safeTransferFrom( 280 | IERC20 token, 281 | address from, 282 | address to, 283 | uint256 value 284 | ) internal { 285 | callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 286 | } 287 | 288 | function safeApprove( 289 | IERC20 token, 290 | address spender, 291 | uint256 value 292 | ) internal { 293 | require( 294 | (value == 0) || (token.allowance(address(this), spender) == 0), 295 | 'SafeERC20: approve from non-zero to non-zero allowance' 296 | ); 297 | callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 298 | } 299 | 300 | function callOptionalReturn(IERC20 token, bytes memory data) private { 301 | require(address(token).isContract(), 'SafeERC20: call to non-contract'); 302 | 303 | // solhint-disable-next-line avoid-low-level-calls 304 | (bool success, bytes memory returndata) = address(token).call(data); 305 | require(success, 'SafeERC20: low-level call failed'); 306 | 307 | if (returndata.length > 0) { 308 | // Return data is optional 309 | // solhint-disable-next-line max-line-length 310 | require(abi.decode(returndata, (bool)), 'SafeERC20: ERC20 operation did not succeed'); 311 | } 312 | } 313 | } 314 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Interfaces.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity 0.6.12; 3 | pragma experimental ABIEncoderV2; 4 | 5 | import { DataTypes } from "./Libraries.sol"; 6 | 7 | /** 8 | * @dev Interface of the ERC165 standard, as defined in the 9 | * https://eips.ethereum.org/EIPS/eip-165[EIP]. 10 | * 11 | * Implementers can declare support of contract interfaces, which can then be 12 | * queried by others ({ERC165Checker}). 13 | * 14 | * For an implementation, see {ERC165}. 15 | */ 16 | interface IERC165 { 17 | /** 18 | * @dev Returns true if this contract implements the interface defined by 19 | * `interfaceId`. See the corresponding 20 | * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] 21 | * to learn more about how these ids are created. 22 | * 23 | * This function call must use less than 30 000 gas. 24 | */ 25 | function supportsInterface(bytes4 interfaceId) external view returns (bool); 26 | } 27 | 28 | /** 29 | * @dev Required interface of an ERC721 compliant contract. 30 | */ 31 | interface IERC721 is IERC165 { 32 | /** 33 | * @dev Emitted when `tokenId` token is transferred from `from` to `to`. 34 | */ 35 | event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); 36 | 37 | /** 38 | * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. 39 | */ 40 | event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); 41 | 42 | /** 43 | * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. 44 | */ 45 | event ApprovalForAll(address indexed owner, address indexed operator, bool approved); 46 | 47 | /** 48 | * @dev Returns the number of tokens in ``owner``'s account. 49 | */ 50 | function balanceOf(address owner) external view returns (uint256 balance); 51 | 52 | /** 53 | * @dev Returns the owner of the `tokenId` token. 54 | * 55 | * Requirements: 56 | * 57 | * - `tokenId` must exist. 58 | */ 59 | function ownerOf(uint256 tokenId) external view returns (address owner); 60 | 61 | /** 62 | * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients 63 | * are aware of the ERC721 protocol to prevent tokens from being forever locked. 64 | * 65 | * Requirements: 66 | * 67 | * - `from` cannot be the zero address. 68 | * - `to` cannot be the zero address. 69 | * - `tokenId` token must exist and be owned by `from`. 70 | * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. 71 | * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. 72 | * 73 | * Emits a {Transfer} event. 74 | */ 75 | function safeTransferFrom(address from, address to, uint256 tokenId) external; 76 | 77 | /** 78 | * @dev Transfers `tokenId` token from `from` to `to`. 79 | * 80 | * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. 81 | * 82 | * Requirements: 83 | * 84 | * - `from` cannot be the zero address. 85 | * - `to` cannot be the zero address. 86 | * - `tokenId` token must be owned by `from`. 87 | * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. 88 | * 89 | * Emits a {Transfer} event. 90 | */ 91 | function transferFrom(address from, address to, uint256 tokenId) external; 92 | 93 | /** 94 | * @dev Gives permission to `to` to transfer `tokenId` token to another account. 95 | * The approval is cleared when the token is transferred. 96 | * 97 | * Only a single account can be approved at a time, so approving the zero address clears previous approvals. 98 | * 99 | * Requirements: 100 | * 101 | * - The caller must own the token or be an approved operator. 102 | * - `tokenId` must exist. 103 | * 104 | * Emits an {Approval} event. 105 | */ 106 | function approve(address to, uint256 tokenId) external; 107 | 108 | /** 109 | * @dev Returns the account approved for `tokenId` token. 110 | * 111 | * Requirements: 112 | * 113 | * - `tokenId` must exist. 114 | */ 115 | function getApproved(uint256 tokenId) external view returns (address operator); 116 | 117 | /** 118 | * @dev Approve or remove `operator` as an operator for the caller. 119 | * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. 120 | * 121 | * Requirements: 122 | * 123 | * - The `operator` cannot be the caller. 124 | * 125 | * Emits an {ApprovalForAll} event. 126 | */ 127 | function setApprovalForAll(address operator, bool _approved) external; 128 | 129 | /** 130 | * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. 131 | * 132 | * See {setApprovalForAll} 133 | */ 134 | function isApprovedForAll(address owner, address operator) external view returns (bool); 135 | 136 | /** 137 | * @dev Safely transfers `tokenId` token from `from` to `to`. 138 | * 139 | * Requirements: 140 | * 141 | * - `from` cannot be the zero address. 142 | * - `to` cannot be the zero address. 143 | * - `tokenId` token must exist and be owned by `from`. 144 | * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. 145 | * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. 146 | * 147 | * Emits a {Transfer} event. 148 | */ 149 | function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; 150 | } 151 | 152 | interface IERC20 { 153 | /** 154 | * @dev Returns the amount of tokens in existence. 155 | */ 156 | function totalSupply() external view returns (uint256); 157 | 158 | /** 159 | * @dev Returns the amount of tokens owned by `account`. 160 | */ 161 | function balanceOf(address account) external view returns (uint256); 162 | 163 | /** 164 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 165 | * 166 | * Returns a boolean value indicating whether the operation succeeded. 167 | * 168 | * Emits a {Transfer} event. 169 | */ 170 | function transfer(address recipient, uint256 amount) external returns (bool); 171 | 172 | /** 173 | * @dev Returns the remaining number of tokens that `spender` will be 174 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 175 | * zero by default. 176 | * 177 | * This value changes when {approve} or {transferFrom} are called. 178 | */ 179 | function allowance(address owner, address spender) external view returns (uint256); 180 | 181 | /** 182 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 183 | * 184 | * Returns a boolean value indicating whether the operation succeeded. 185 | * 186 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 187 | * that someone may use both the old and the new allowance by unfortunate 188 | * transaction ordering. One possible solution to mitigate this race 189 | * condition is to first reduce the spender's allowance to 0 and set the 190 | * desired value afterwards: 191 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 192 | * 193 | * Emits an {Approval} event. 194 | */ 195 | function approve(address spender, uint256 amount) external returns (bool); 196 | 197 | /** 198 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 199 | * allowance mechanism. `amount` is then deducted from the caller's 200 | * allowance. 201 | * 202 | * Returns a boolean value indicating whether the operation succeeded. 203 | * 204 | * Emits a {Transfer} event. 205 | */ 206 | function transferFrom( 207 | address sender, 208 | address recipient, 209 | uint256 amount 210 | ) external returns (bool); 211 | 212 | /** 213 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 214 | * another (`to`). 215 | * 216 | * Note that `value` may be zero. 217 | */ 218 | event Transfer(address indexed from, address indexed to, uint256 value); 219 | 220 | /** 221 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 222 | * a call to {approve}. `value` is the new allowance. 223 | */ 224 | event Approval(address indexed owner, address indexed spender, uint256 value); 225 | } 226 | 227 | interface IProtocolDataProvider { 228 | struct TokenData { 229 | string symbol; 230 | address tokenAddress; 231 | } 232 | 233 | function ADDRESSES_PROVIDER() external view returns (ILendingPoolAddressesProvider); 234 | function getAllReservesTokens() external view returns (TokenData[] memory); 235 | function getAllATokens() external view returns (TokenData[] memory); 236 | function getReserveConfigurationData(address asset) external view returns (uint256 decimals, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, uint256 reserveFactor, bool usageAsCollateralEnabled, bool borrowingEnabled, bool stableBorrowRateEnabled, bool isActive, bool isFrozen); 237 | function getReserveData(address asset) external view returns (uint256 availableLiquidity, uint256 totalStableDebt, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, uint256 averageStableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp); 238 | function getUserReserveData(address asset, address user) external view returns (uint256 currentATokenBalance, uint256 currentStableDebt, uint256 currentVariableDebt, uint256 principalStableDebt, uint256 scaledVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, uint40 stableRateLastUpdated, bool usageAsCollateralEnabled); 239 | function getReserveTokensAddresses(address asset) external view returns (address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress); 240 | } 241 | 242 | interface ILendingPoolAddressesProvider { 243 | event MarketIdSet(string newMarketId); 244 | event LendingPoolUpdated(address indexed newAddress); 245 | event ConfigurationAdminUpdated(address indexed newAddress); 246 | event EmergencyAdminUpdated(address indexed newAddress); 247 | event LendingPoolConfiguratorUpdated(address indexed newAddress); 248 | event LendingPoolCollateralManagerUpdated(address indexed newAddress); 249 | event PriceOracleUpdated(address indexed newAddress); 250 | event LendingRateOracleUpdated(address indexed newAddress); 251 | event ProxyCreated(bytes32 id, address indexed newAddress); 252 | event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy); 253 | 254 | function getMarketId() external view returns (string memory); 255 | 256 | function setMarketId(string calldata marketId) external; 257 | 258 | function setAddress(bytes32 id, address newAddress) external; 259 | 260 | function setAddressAsProxy(bytes32 id, address impl) external; 261 | 262 | function getAddress(bytes32 id) external view returns (address); 263 | 264 | function getLendingPool() external view returns (address); 265 | 266 | function setLendingPoolImpl(address pool) external; 267 | 268 | function getLendingPoolConfigurator() external view returns (address); 269 | 270 | function setLendingPoolConfiguratorImpl(address configurator) external; 271 | 272 | function getLendingPoolCollateralManager() external view returns (address); 273 | 274 | function setLendingPoolCollateralManager(address manager) external; 275 | 276 | function getPoolAdmin() external view returns (address); 277 | 278 | function setPoolAdmin(address admin) external; 279 | 280 | function getEmergencyAdmin() external view returns (address); 281 | 282 | function setEmergencyAdmin(address admin) external; 283 | 284 | function getPriceOracle() external view returns (address); 285 | 286 | function setPriceOracle(address priceOracle) external; 287 | 288 | function getLendingRateOracle() external view returns (address); 289 | 290 | function setLendingRateOracle(address lendingRateOracle) external; 291 | } 292 | 293 | interface ILendingPool { 294 | /** 295 | * @dev Emitted on deposit() 296 | * @param reserve The address of the underlying asset of the reserve 297 | * @param user The address initiating the deposit 298 | * @param onBehalfOf The beneficiary of the deposit, receiving the aTokens 299 | * @param amount The amount deposited 300 | * @param referral The referral code used 301 | **/ 302 | event Deposit( 303 | address indexed reserve, 304 | address user, 305 | address indexed onBehalfOf, 306 | uint256 amount, 307 | uint16 indexed referral 308 | ); 309 | 310 | /** 311 | * @dev Emitted on withdraw() 312 | * @param reserve The address of the underlyng asset being withdrawn 313 | * @param user The address initiating the withdrawal, owner of aTokens 314 | * @param to Address that will receive the underlying 315 | * @param amount The amount to be withdrawn 316 | **/ 317 | event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); 318 | 319 | /** 320 | * @dev Emitted on borrow() and flashLoan() when debt needs to be opened 321 | * @param reserve The address of the underlying asset being borrowed 322 | * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just 323 | * initiator of the transaction on flashLoan() 324 | * @param onBehalfOf The address that will be getting the debt 325 | * @param amount The amount borrowed out 326 | * @param borrowRateMode The rate mode: 1 for Stable, 2 for Variable 327 | * @param borrowRate The numeric rate at which the user has borrowed 328 | * @param referral The referral code used 329 | **/ 330 | event Borrow( 331 | address indexed reserve, 332 | address user, 333 | address indexed onBehalfOf, 334 | uint256 amount, 335 | uint256 borrowRateMode, 336 | uint256 borrowRate, 337 | uint16 indexed referral 338 | ); 339 | 340 | /** 341 | * @dev Emitted on repay() 342 | * @param reserve The address of the underlying asset of the reserve 343 | * @param user The beneficiary of the repayment, getting his debt reduced 344 | * @param repayer The address of the user initiating the repay(), providing the funds 345 | * @param amount The amount repaid 346 | **/ 347 | event Repay( 348 | address indexed reserve, 349 | address indexed user, 350 | address indexed repayer, 351 | uint256 amount 352 | ); 353 | 354 | /** 355 | * @dev Emitted on swapBorrowRateMode() 356 | * @param reserve The address of the underlying asset of the reserve 357 | * @param user The address of the user swapping his rate mode 358 | * @param rateMode The rate mode that the user wants to swap to 359 | **/ 360 | event Swap(address indexed reserve, address indexed user, uint256 rateMode); 361 | 362 | /** 363 | * @dev Emitted on setUserUseReserveAsCollateral() 364 | * @param reserve The address of the underlying asset of the reserve 365 | * @param user The address of the user enabling the usage as collateral 366 | **/ 367 | event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); 368 | 369 | /** 370 | * @dev Emitted on setUserUseReserveAsCollateral() 371 | * @param reserve The address of the underlying asset of the reserve 372 | * @param user The address of the user enabling the usage as collateral 373 | **/ 374 | event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); 375 | 376 | /** 377 | * @dev Emitted on rebalanceStableBorrowRate() 378 | * @param reserve The address of the underlying asset of the reserve 379 | * @param user The address of the user for which the rebalance has been executed 380 | **/ 381 | event RebalanceStableBorrowRate(address indexed reserve, address indexed user); 382 | 383 | /** 384 | * @dev Emitted on flashLoan() 385 | * @param target The address of the flash loan receiver contract 386 | * @param initiator The address initiating the flash loan 387 | * @param asset The address of the asset being flash borrowed 388 | * @param amount The amount flash borrowed 389 | * @param premium The fee flash borrowed 390 | * @param referralCode The referral code used 391 | **/ 392 | event FlashLoan( 393 | address indexed target, 394 | address indexed initiator, 395 | address indexed asset, 396 | uint256 amount, 397 | uint256 premium, 398 | uint16 referralCode 399 | ); 400 | 401 | /** 402 | * @dev Emitted when the pause is triggered. 403 | */ 404 | event Paused(); 405 | 406 | /** 407 | * @dev Emitted when the pause is lifted. 408 | */ 409 | event Unpaused(); 410 | 411 | /** 412 | * @dev Emitted when a borrower is liquidated. This event is emitted by the LendingPool via 413 | * LendingPoolCollateral manager using a DELEGATECALL 414 | * This allows to have the events in the generated ABI for LendingPool. 415 | * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation 416 | * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation 417 | * @param user The address of the borrower getting liquidated 418 | * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover 419 | * @param liquidatedCollateralAmount The amount of collateral received by the liiquidator 420 | * @param liquidator The address of the liquidator 421 | * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants 422 | * to receive the underlying collateral asset directly 423 | **/ 424 | event LiquidationCall( 425 | address indexed collateralAsset, 426 | address indexed debtAsset, 427 | address indexed user, 428 | uint256 debtToCover, 429 | uint256 liquidatedCollateralAmount, 430 | address liquidator, 431 | bool receiveAToken 432 | ); 433 | 434 | /** 435 | * @dev Emitted when the state of a reserve is updated. NOTE: This event is actually declared 436 | * in the ReserveLogic library and emitted in the updateInterestRates() function. Since the function is internal, 437 | * the event will actually be fired by the LendingPool contract. The event is therefore replicated here so it 438 | * gets added to the LendingPool ABI 439 | * @param reserve The address of the underlying asset of the reserve 440 | * @param liquidityRate The new liquidity rate 441 | * @param stableBorrowRate The new stable borrow rate 442 | * @param variableBorrowRate The new variable borrow rate 443 | * @param liquidityIndex The new liquidity index 444 | * @param variableBorrowIndex The new variable borrow index 445 | **/ 446 | event ReserveDataUpdated( 447 | address indexed reserve, 448 | uint256 liquidityRate, 449 | uint256 stableBorrowRate, 450 | uint256 variableBorrowRate, 451 | uint256 liquidityIndex, 452 | uint256 variableBorrowIndex 453 | ); 454 | 455 | /** 456 | * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. 457 | * - E.g. User deposits 100 USDC and gets in return 100 aUSDC 458 | * @param asset The address of the underlying asset to deposit 459 | * @param amount The amount to be deposited 460 | * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user 461 | * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens 462 | * is a different wallet 463 | * @param referralCode Code used to register the integrator originating the operation, for potential rewards. 464 | * 0 if the action is executed directly by the user, without any middle-man 465 | **/ 466 | function deposit( 467 | address asset, 468 | uint256 amount, 469 | address onBehalfOf, 470 | uint16 referralCode 471 | ) external; 472 | 473 | /** 474 | * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned 475 | * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC 476 | * @param asset The address of the underlying asset to withdraw 477 | * @param amount The underlying amount to be withdrawn 478 | * - Send the value type(uint256).max in order to withdraw the whole aToken balance 479 | * @param to Address that will receive the underlying, same as msg.sender if the user 480 | * wants to receive it on his own wallet, or a different address if the beneficiary is a 481 | * different wallet 482 | * @return The final amount withdrawn 483 | **/ 484 | function withdraw( 485 | address asset, 486 | uint256 amount, 487 | address to 488 | ) external returns (uint256); 489 | 490 | /** 491 | * @dev Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower 492 | * already deposited enough collateral, or he was given enough allowance by a credit delegator on the 493 | * corresponding debt token (StableDebtToken or VariableDebtToken) 494 | * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet 495 | * and 100 stable/variable debt tokens, depending on the `interestRateMode` 496 | * @param asset The address of the underlying asset to borrow 497 | * @param amount The amount to be borrowed 498 | * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable 499 | * @param referralCode Code used to register the integrator originating the operation, for potential rewards. 500 | * 0 if the action is executed directly by the user, without any middle-man 501 | * @param onBehalfOf Address of the user who will receive the debt. Should be the address of the borrower itself 502 | * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator 503 | * if he has been given credit delegation allowance 504 | **/ 505 | function borrow( 506 | address asset, 507 | uint256 amount, 508 | uint256 interestRateMode, 509 | uint16 referralCode, 510 | address onBehalfOf 511 | ) external; 512 | 513 | /** 514 | * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned 515 | * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address 516 | * @param asset The address of the borrowed underlying asset previously borrowed 517 | * @param amount The amount to repay 518 | * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` 519 | * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable 520 | * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the 521 | * user calling the function if he wants to reduce/remove his own debt, or the address of any other 522 | * other borrower whose debt should be removed 523 | * @return The final amount repaid 524 | **/ 525 | function repay( 526 | address asset, 527 | uint256 amount, 528 | uint256 rateMode, 529 | address onBehalfOf 530 | ) external returns (uint256); 531 | 532 | /** 533 | * @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa 534 | * @param asset The address of the underlying asset borrowed 535 | * @param rateMode The rate mode that the user wants to swap to 536 | **/ 537 | function swapBorrowRateMode(address asset, uint256 rateMode) external; 538 | 539 | /** 540 | * @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. 541 | * - Users can be rebalanced if the following conditions are satisfied: 542 | * 1. Usage ratio is above 95% 543 | * 2. the current deposit APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too much has been 544 | * borrowed at a stable rate and depositors are not earning enough 545 | * @param asset The address of the underlying asset borrowed 546 | * @param user The address of the user to be rebalanced 547 | **/ 548 | function rebalanceStableBorrowRate(address asset, address user) external; 549 | 550 | /** 551 | * @dev Allows depositors to enable/disable a specific deposited asset as collateral 552 | * @param asset The address of the underlying asset deposited 553 | * @param useAsCollateral `true` if the user wants to use the deposit as collateral, `false` otherwise 554 | **/ 555 | function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; 556 | 557 | /** 558 | * @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 559 | * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives 560 | * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk 561 | * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation 562 | * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation 563 | * @param user The address of the borrower getting liquidated 564 | * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover 565 | * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants 566 | * to receive the underlying collateral asset directly 567 | **/ 568 | function liquidationCall( 569 | address collateralAsset, 570 | address debtAsset, 571 | address user, 572 | uint256 debtToCover, 573 | bool receiveAToken 574 | ) external; 575 | 576 | /** 577 | * @dev Allows smartcontracts to access the liquidity of the pool within one transaction, 578 | * as long as the amount taken plus a fee is returned. 579 | * IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept into consideration. 580 | * For further details please visit https://developers.aave.com 581 | * @param receiverAddress The address of the contract receiving the funds, implementing the IFlashLoanReceiver interface 582 | * @param assets The addresses of the assets being flash-borrowed 583 | * @param amounts The amounts amounts being flash-borrowed 584 | * @param modes Types of the debt to open if the flash loan is not returned: 585 | * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver 586 | * 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address 587 | * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address 588 | * @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2 589 | * @param params Variadic packed params to pass to the receiver as extra information 590 | * @param referralCode Code used to register the integrator originating the operation, for potential rewards. 591 | * 0 if the action is executed directly by the user, without any middle-man 592 | **/ 593 | function flashLoan( 594 | address receiverAddress, 595 | address[] calldata assets, 596 | uint256[] calldata amounts, 597 | uint256[] calldata modes, 598 | address onBehalfOf, 599 | bytes calldata params, 600 | uint16 referralCode 601 | ) external; 602 | 603 | /** 604 | * @dev Returns the user account data across all the reserves 605 | * @param user The address of the user 606 | * @return totalCollateralETH the total collateral in ETH of the user 607 | * @return totalDebtETH the total debt in ETH of the user 608 | * @return availableBorrowsETH the borrowing power left of the user 609 | * @return currentLiquidationThreshold the liquidation threshold of the user 610 | * @return ltv the loan to value of the user 611 | * @return healthFactor the current health factor of the user 612 | **/ 613 | function getUserAccountData(address user) 614 | external 615 | view 616 | returns ( 617 | uint256 totalCollateralETH, 618 | uint256 totalDebtETH, 619 | uint256 availableBorrowsETH, 620 | uint256 currentLiquidationThreshold, 621 | uint256 ltv, 622 | uint256 healthFactor 623 | ); 624 | 625 | function initReserve( 626 | address reserve, 627 | address aTokenAddress, 628 | address stableDebtAddress, 629 | address variableDebtAddress, 630 | address interestRateStrategyAddress 631 | ) external; 632 | 633 | function setReserveInterestRateStrategyAddress(address reserve, address rateStrategyAddress) 634 | external; 635 | 636 | function setConfiguration(address reserve, uint256 configuration) external; 637 | 638 | /** 639 | * @dev Returns the configuration of the reserve 640 | * @param asset The address of the underlying asset of the reserve 641 | * @return The configuration of the reserve 642 | **/ 643 | function getConfiguration(address asset) 644 | external 645 | view 646 | returns (DataTypes.ReserveConfigurationMap memory); 647 | 648 | /** 649 | * @dev Returns the configuration of the user across all the reserves 650 | * @param user The user address 651 | * @return The configuration of the user 652 | **/ 653 | function getUserConfiguration(address user) 654 | external 655 | view 656 | returns (DataTypes.UserConfigurationMap memory); 657 | 658 | /** 659 | * @dev Returns the normalized income normalized income of the reserve 660 | * @param asset The address of the underlying asset of the reserve 661 | * @return The reserve's normalized income 662 | */ 663 | function getReserveNormalizedIncome(address asset) external view returns (uint256); 664 | 665 | /** 666 | * @dev Returns the normalized variable debt per unit of asset 667 | * @param asset The address of the underlying asset of the reserve 668 | * @return The reserve normalized variable debt 669 | */ 670 | function getReserveNormalizedVariableDebt(address asset) external view returns (uint256); 671 | 672 | /** 673 | * @dev Returns the state and configuration of the reserve 674 | * @param asset The address of the underlying asset of the reserve 675 | * @return The state of the reserve 676 | **/ 677 | function getReserveData(address asset) external view returns (DataTypes.ReserveData memory); 678 | 679 | function finalizeTransfer( 680 | address asset, 681 | address from, 682 | address to, 683 | uint256 amount, 684 | uint256 balanceFromAfter, 685 | uint256 balanceToBefore 686 | ) external; 687 | 688 | function getReservesList() external view returns (address[] memory); 689 | 690 | function getAddressesProvider() external view returns (ILendingPoolAddressesProvider); 691 | 692 | function setPause(bool val) external; 693 | 694 | function paused() external view returns (bool); 695 | } 696 | 697 | interface IStableDebtToken { 698 | /** 699 | * @dev Emitted when new stable debt is minted 700 | * @param user The address of the user who triggered the minting 701 | * @param onBehalfOf The recipient of stable debt tokens 702 | * @param amount The amount minted 703 | * @param currentBalance The current balance of the user 704 | * @param balanceIncrease The increase in balance since the last action of the user 705 | * @param newRate The rate of the debt after the minting 706 | * @param avgStableRate The new average stable rate after the minting 707 | * @param newTotalSupply The new total supply of the stable debt token after the action 708 | **/ 709 | event Mint( 710 | address indexed user, 711 | address indexed onBehalfOf, 712 | uint256 amount, 713 | uint256 currentBalance, 714 | uint256 balanceIncrease, 715 | uint256 newRate, 716 | uint256 avgStableRate, 717 | uint256 newTotalSupply 718 | ); 719 | 720 | /** 721 | * @dev Emitted when new stable debt is burned 722 | * @param user The address of the user 723 | * @param amount The amount being burned 724 | * @param currentBalance The current balance of the user 725 | * @param balanceIncrease The the increase in balance since the last action of the user 726 | * @param avgStableRate The new average stable rate after the burning 727 | * @param newTotalSupply The new total supply of the stable debt token after the action 728 | **/ 729 | event Burn( 730 | address indexed user, 731 | uint256 amount, 732 | uint256 currentBalance, 733 | uint256 balanceIncrease, 734 | uint256 avgStableRate, 735 | uint256 newTotalSupply 736 | ); 737 | 738 | /** 739 | * @dev delegates borrowing power to a user on the specific debt token 740 | * @param delegatee the address receiving the delegated borrowing power 741 | * @param amount the maximum amount being delegated. Delegation will still 742 | * respect the liquidation constraints (even if delegated, a delegatee cannot 743 | * force a delegator HF to go below 1) 744 | **/ 745 | function approveDelegation(address delegatee, uint256 amount) external; 746 | 747 | /** 748 | * @dev returns the borrow allowance of the user 749 | * @param fromUser The user to giving allowance 750 | * @param toUser The user to give allowance to 751 | * @return the current allowance of toUser 752 | **/ 753 | function borrowAllowance(address fromUser, address toUser) external view returns (uint256); 754 | 755 | /** 756 | * @dev Mints debt token to the `onBehalfOf` address. 757 | * - The resulting rate is the weighted average between the rate of the new debt 758 | * and the rate of the previous debt 759 | * @param user The address receiving the borrowed underlying, being the delegatee in case 760 | * of credit delegate, or same as `onBehalfOf` otherwise 761 | * @param onBehalfOf The address receiving the debt tokens 762 | * @param amount The amount of debt tokens to mint 763 | * @param rate The rate of the debt being minted 764 | **/ 765 | function mint( 766 | address user, 767 | address onBehalfOf, 768 | uint256 amount, 769 | uint256 rate 770 | ) external returns (bool); 771 | 772 | /** 773 | * @dev Burns debt of `user` 774 | * - The resulting rate is the weighted average between the rate of the new debt 775 | * and the rate of the previous debt 776 | * @param user The address of the user getting his debt burned 777 | * @param amount The amount of debt tokens getting burned 778 | **/ 779 | function burn(address user, uint256 amount) external; 780 | 781 | /** 782 | * @dev Returns the average rate of all the stable rate loans. 783 | * @return The average stable rate 784 | **/ 785 | function getAverageStableRate() external view returns (uint256); 786 | 787 | /** 788 | * @dev Returns the stable rate of the user debt 789 | * @return The stable rate of the user 790 | **/ 791 | function getUserStableRate(address user) external view returns (uint256); 792 | 793 | /** 794 | * @dev Returns the timestamp of the last update of the user 795 | * @return The timestamp 796 | **/ 797 | function getUserLastUpdated(address user) external view returns (uint40); 798 | 799 | /** 800 | * @dev Returns the principal, the total supply and the average stable rate 801 | **/ 802 | function getSupplyData() 803 | external 804 | view 805 | returns ( 806 | uint256, 807 | uint256, 808 | uint256, 809 | uint40 810 | ); 811 | 812 | /** 813 | * @dev Returns the timestamp of the last update of the total supply 814 | * @return The timestamp 815 | **/ 816 | function getTotalSupplyLastUpdated() external view returns (uint40); 817 | 818 | /** 819 | * @dev Returns the total supply and the average stable rate 820 | **/ 821 | function getTotalSupplyAndAvgRate() external view returns (uint256, uint256); 822 | 823 | /** 824 | * @dev Returns the principal debt balance of the user 825 | * @return The debt balance of the user since the last burn/mint action 826 | **/ 827 | function principalBalanceOf(address user) external view returns (uint256); 828 | 829 | /** 830 | * @dev Calculates the current user debt balance 831 | * @return The accumulated debt of the user 832 | **/ 833 | function balanceOf(address account) external view returns (uint256); 834 | } 835 | --------------------------------------------------------------------------------