Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 19675968 | 134 days ago | IN | 0 ETH | 0.08893508 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
DoughIndex
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.8.24; import "./DoughDsa.sol"; import "@openzeppelin/contracts/proxy/Clones.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import { IDoughIndex, IBorrowManagementConnector, CustomError } from "./Interfaces.sol"; import { DoughCore } from "./libraries/DoughCore.sol"; /** * $$$$$$$\ $$\ $$$$$$$$\ $$\ * $$ __$$\ $$ | $$ _____|\__| * $$ | $$ | $$$$$$\ $$\ $$\ $$$$$$\ $$$$$$$\ $$ | $$\ $$$$$$$\ $$$$$$\ $$$$$$$\ $$$$$$$\ $$$$$$\ * $$ | $$ |$$ __$$\ $$ | $$ |$$ __$$\ $$ __$$\ $$$$$\ $$ |$$ __$$\ \____$$\ $$ __$$\ $$ _____|$$ __$$\ * $$ | $$ |$$ / $$ |$$ | $$ |$$ / $$ |$$ | $$ | $$ __| $$ |$$ | $$ | $$$$$$$ |$$ | $$ |$$ / $$$$$$$$ | * $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ | $$ | $$ |$$ | $$ |$$ __$$ |$$ | $$ |$$ | $$ ____| * $$$$$$$ |\$$$$$$ |\$$$$$$ |\$$$$$$$ |$$ | $$ | $$ | $$ |$$ | $$ |\$$$$$$$ |$$ | $$ |\$$$$$$$\ \$$$$$$$\ * \_______/ \______/ \______/ \____$$ |\__| \__| \__| \__|\__| \__| \_______|\__| \__| \_______| \_______| * $$\ $$ | * \$$$$$$ | * \______/ * * @title DoughIndex * @notice This contract is used to manage the Dough Finance Settings and Connectors * @custom:version 1.0 - Initial release * @author Liberalite https://github.com/liberalite * @custom:coauthor 0xboga https://github.com/0xboga */ contract DoughIndex is Initializable { using SafeERC20 for IERC20; /* ========== EVENTS ========== */ event AllowOnlyEOA(bool status); event ApyFeeUpdated(uint256 apyFee); event DsaCreated(address indexed newDsaAddress, address indexed ownerAddress); event ConnectorUpdated(uint256 connectorId, address connectorAddress); event UpdateBorrowDate(address caller, address dsaAddress, address token, uint256 connector, uint256 timeNow); event NewTokenWhitelisted(address token, uint8 decimals, uint256 minInterest); event DeletedTokenWhitelisted(address token); event NewDoughMultisig(address newMultisig); event NewDoughIndex(address newDoughIndex); event NewMinHealthFactor(uint256 feeRatio); event NewDeleverageAsset(address deleverageAsset); event NewTreasuryAddress(address treasuryAddress); event NewDeleveragingRatio(uint256 minDeleveragingRatio); event NewDeleverageAutomation(address deleverageAutomation); event NewShieldAutomation(address shieldAutomation); event NewVaultAutomation(address vaultAutomation); event NewFlashBorrower(address flashBorrower, bool status); event NewBorrowFormula(address borrowFormula); event NewAaveActionsConnector(address aaveActionsConnector); event NewDsaMasterClone(address dsaMasterClone); /* ========== STORAGE VARIABLES ========== */ bool public allowOnlyEOA; uint256 public apyFee; uint256 public dsaCounter; uint256 public minHealthFactor; uint256 public minDeleveragingRatio; address[] public whitelistedTokenList; address public dsaMasterCopy; address public multisig; address public treasury; address public deleverageAsset; address public borrowFormulaAddress; address public aaveActionsAddress; address public deleverageAutomation; address public shieldAutomation; address public vaultAutomation; /* ========== STRUCT ========== */ struct WhitelistedTokens { uint8 decimals; uint256 minInterest; uint256 tokenIndex; } /* ========== MAPPINGS ========== */ mapping(address => mapping(address => uint256)) private _dsaTokenBorrowStartDate; mapping(address => WhitelistedTokens) public whitelistedTokens; mapping(address => address) private getDsaOfOwner; mapping(address => address) public getOwnerOfDoughDsa; mapping(uint256 => address) public getDsaByID; mapping(uint256 => address) public getDoughConnector; mapping(address => bool) public getFlashBorrowers; /* ========== MODIFIERS ========== */ modifier onlyMultisig { if(msg.sender != multisig) revert CustomError("Invalid multisig address"); _; } /** * @notice Initialize the Dough Index contract * @param _multisig The address of the multisig * @param _treasury The address of the treasury * @param _deleveratingAsset The address of the preferred asset for deleveraging * @param _deleverageAutomation The address of the deleveraging automation contract * @param _apyFee The fee to be charged for the APY * @param _minDeleveragingRatio The minimum deleveraging ratio * @param _minHealthFactorRatio The minimum allowed health factor ratio */ function initialize( address _multisig, address _treasury, address _deleveratingAsset, address _deleverageAutomation, uint256 _apyFee, uint256 _minDeleveragingRatio, uint256 _minHealthFactorRatio ) public initializer { deleverageAutomation = _deleverageAutomation; minDeleveragingRatio = _minDeleveragingRatio; minHealthFactor = _minHealthFactorRatio; deleverageAsset = _deleveratingAsset; multisig = _multisig; treasury = _treasury; apyFee = _apyFee; allowOnlyEOA = true; } /** * @notice Function to set new DSA Master Clone * @param _dsaMasterCopy The address of the new DSA Master Clone * @dev Only the multisig can call this function */ function setDsaMasterClone(address _dsaMasterCopy) external onlyMultisig { if (_dsaMasterCopy == address(0)) revert CustomError("Invalid zero address"); dsaMasterCopy = _dsaMasterCopy; emit NewDsaMasterClone(_dsaMasterCopy); } /** * @notice Function to set new recipe for the Dough Index Borrow Formula * @param _newBorrowFormula The address of the new borrow formula contract * @dev Only the multisig can call this function */ function setNewBorrowFormula(address _newBorrowFormula) external onlyMultisig { if (_newBorrowFormula == address(0)) revert CustomError("Invalid zero address"); borrowFormulaAddress = _newBorrowFormula; emit NewBorrowFormula(_newBorrowFormula); } /** * @notice Function to set new Aave Actions Connector * @param _newAaveActions The address of the new Aave Actions Connector * @dev Only the multisig can call this function */ function setNewAaveActions(address _newAaveActions) external onlyMultisig { if (_newAaveActions == address(0)) revert CustomError("Invalid zero address"); aaveActionsAddress = _newAaveActions; emit NewAaveActionsConnector(_newAaveActions); } /** * @notice Function to set new Deleveraging Automation * @param _deleverageAutomation The address of the new deleveraging automation contract * @dev Only the multisig can call this function */ function setDeleverageAutomation(address _deleverageAutomation) external onlyMultisig { deleverageAutomation = _deleverageAutomation; emit NewDeleverageAutomation(_deleverageAutomation); } /** * @notice Function to set new Chainlink Shield Automation * @param _shieldAutomation The address of the new shield automation contract * @dev Only the multisig can call this function */ function setNewShieldAutomation(address _shieldAutomation) external onlyMultisig { shieldAutomation = _shieldAutomation; emit NewShieldAutomation(_shieldAutomation); } /** * @notice Function to set new recipe for the Dough Index Borrow Formula * @param _vaultAutomation The address of the new borrow formula contract * @dev Only the multisig can call this function */ function setNewVaultAutomation(address _vaultAutomation) external onlyMultisig { vaultAutomation = _vaultAutomation; emit NewVaultAutomation(_vaultAutomation); } /** * @notice Function to delete a whitelisted token address * @param _token The address of the token to be deleted * @dev Only the multisig can call this function */ function deleteWhitelistedTokenAddress(address _token) external onlyMultisig { if (_token == address(0)) revert CustomError("Invalid zero address"); uint256 lastKey = whitelistedTokenList.length - 1; address lastTokenAddress = whitelistedTokenList[lastKey]; if(lastTokenAddress == _token) { whitelistedTokenList.pop(); delete whitelistedTokens[_token]; emit DeletedTokenWhitelisted(_token); return; } whitelistedTokens[lastTokenAddress].tokenIndex = lastKey; uint256 indexNr = whitelistedTokens[_token].tokenIndex; whitelistedTokenList[indexNr] = whitelistedTokenList[lastKey]; whitelistedTokenList.pop(); delete whitelistedTokens[_token]; emit DeletedTokenWhitelisted(_token); } /** * @notice Function to set a new whitelisted token * @param _token The address of the token to be whitelisted * @param _decimals The decimals of the token * @param _minInterest The minimum interest of the token * @dev Only the multisig can call this function */ function setNewWhitelistedToken(address _token, uint8 _decimals, uint256 _minInterest) external onlyMultisig { if (_token == address(0)) revert CustomError("Invalid zero address"); if (_decimals == 0) revert CustomError("Invalid token decimals"); whitelistedTokens[_token] = WhitelistedTokens(_decimals, _minInterest, whitelistedTokenList.length); whitelistedTokenList.push(_token); emit NewTokenWhitelisted(_token, _decimals, _minInterest); } /** * @notice Function to get the address of the DoughDsa contract * @param _flashBorrower The address of the flash borrower * @param _status The status of the flash borrower * @dev Only the multisig can call this function */ function setFlashBorrower(address _flashBorrower, bool _status) public onlyMultisig { getFlashBorrowers[_flashBorrower] = _status; address dsa = getDsaOfOwner[_flashBorrower]; uint256 whitelistedTokensLength = whitelistedTokenList.length; if(_status == true) { for (uint i = 0; i < whitelistedTokensLength;) { _dsaTokenBorrowStartDate[dsa][whitelistedTokenList[i]] = 0; unchecked { i++; } } } emit NewFlashBorrower(_flashBorrower, _status); } /** * Function to set the multiple flash borrowers * @param _flashBorrowers The addresses of the flash borrowers * @param _status The status of the flash borrowers * @dev Only the multisig can call this function */ function setMultipleFlashBorrowers(address[] calldata _flashBorrowers, bool[] calldata _status) external onlyMultisig { for (uint256 i = 0; i < _flashBorrowers.length;) { setFlashBorrower(_flashBorrowers[i], _status[i]); unchecked { i++; } } } /** * @notice Function to set the minimum allowed health factor ratio * @param _minHealthFactor The minimum allowed health factor ratio * @dev Only the multisig can call this function */ function setMinAllowedHealthFactorRatio(uint256 _minHealthFactor) external onlyMultisig { minHealthFactor = _minHealthFactor; emit NewMinHealthFactor(_minHealthFactor); } /** * @notice Function to set a new multisig for the Dough Index contract * @param _newMultiSig Only the multisig address can change the new multisig * @dev Only the multisig can call this function */ function setNewMultisig(address _newMultiSig) external onlyMultisig { if (_newMultiSig == address(0)) revert CustomError("Invalid zero address"); multisig = _newMultiSig; emit NewDoughMultisig(_newMultiSig); } /** * @notice Function to set the preferred asset for deleveraging * @param _deleverageAsset The address of the preferred asset for deleveraging * @dev Only the multisig can call this function */ function updateDeleverageAsset(address _deleverageAsset) external onlyMultisig { if (_deleverageAsset == address(0)) revert CustomError("Invalid zero address"); if (whitelistedTokens[_deleverageAsset].decimals == 0) revert CustomError("token is not whitelisted"); deleverageAsset = _deleverageAsset; emit NewDeleverageAsset(_deleverageAsset); } /** * @notice Function to set the minimum deleveraging ratio * @param _minDeleveragingRatio The minimum deleveraging ratio * @dev Only the multisig can call this function */ function setMinDeleveragingRatio(uint256 _minDeleveragingRatio) external onlyMultisig { minDeleveragingRatio = _minDeleveragingRatio; emit NewDeleveragingRatio(_minDeleveragingRatio); } /** * @notice Function to set the treasury address * @param _treasury The address of the treasury * @dev Only the multisig can call this function */ function setTreasury(address _treasury) external onlyMultisig { if (_treasury == address(0)) revert CustomError("Invalid zero address"); treasury = _treasury; emit NewTreasuryAddress(_treasury); } /** * @notice Function to set the APY fee * @param _apyFee The fee to be charged for the APY * @dev Only the multisig can call this function */ function setApyFee(uint256 _apyFee) external onlyMultisig { apyFee = _apyFee; emit ApyFeeUpdated(_apyFee); } /** * @notice Function to set the connectors * @param _connectorId The ID of the connector * @param _connectorsAddr The address of the connector * @dev Only the multisig can call this function */ function setConnectors(uint256 _connectorId, address _connectorsAddr) external onlyMultisig { getDoughConnector[_connectorId] = _connectorsAddr; emit ConnectorUpdated(_connectorId, _connectorsAddr); } /** * @notice Function to set only EOA * @param _status The status of the EOA * @dev Only the multisig can call this function */ function setAllowOnlyEOA(bool _status) external onlyMultisig { allowOnlyEOA = _status; emit AllowOnlyEOA(_status); } /** * @notice Function to withdraw accidentaly sent ETH/ERC20 tokens to the connector * @param _asset The address of the ETH/ERC20 token * @param _treasury The address of the treasury * @param _amount The amount of ETH/ERC20 token to withdraw */ function withdrawToken(address _asset, address _treasury, uint256 _amount) external onlyMultisig { if (_amount == 0) revert CustomError("must be greater than zero"); if (_asset == DoughCore.ETH) { payable(_treasury).transfer(_amount); } else { uint256 balanceOfToken = IERC20(_asset).balanceOf(address(this)); uint256 transferAmount = _amount; if (_amount > balanceOfToken) { transferAmount = balanceOfToken; } IERC20(_asset).safeTransfer(_treasury, transferAmount); } } /** * @notice Function to get the owner of the DSA * @param _dsaAddress The address of the DSA */ function getDoughDsa(address _dsaAddress) external view returns (address) { return getDsaOfOwner[_dsaAddress]; } /** * @notice Function to build a new DSA * @return address The address of the new DSA */ function buildDoughDsa() external returns (address) { if (getDsaOfOwner[msg.sender] != address(0)) revert CustomError("DSA already created"); if (allowOnlyEOA && isContract(msg.sender)) revert CustomError("DSA not contract-owned"); address newDoughDsa = Clones.clone(dsaMasterCopy); DoughDsa(payable(newDoughDsa)).initialize(msg.sender, address(this)); getDsaOfOwner[msg.sender] = newDoughDsa; getOwnerOfDoughDsa[newDoughDsa] = msg.sender; getDsaByID[dsaCounter] = newDoughDsa; dsaCounter++; emit DsaCreated(newDoughDsa, msg.sender); return address(newDoughDsa); } /** * @notice Function to get DSA token borrow start date * @param _dsaAddress The address of the DSA * @param _token The address of the token * @return uint256 The start date of the borrow */ function getDsaBorrowStartDate(address _dsaAddress, address _token) external view returns (uint256) { return _dsaTokenBorrowStartDate[_dsaAddress][_token]; } /** * @notice Function to get whitelisted token list * @return address[] The list of whitelisted tokens */ function getWhitelistedTokenList() external view returns (address[] memory) { return whitelistedTokenList; } /** * @notice Function to get the token decimals * @param _token The address of the token * @return uint8 The decimals of the token */ function getTokenDecimals(address _token) external view returns (uint8) { return whitelistedTokens[_token].decimals; } /** * @notice Function to get the token min interest * @param _token The address of the token * @return uint256 The minimum interest of the token */ function getTokenMinInterest(address _token) external view returns (uint256) { return whitelistedTokens[_token].minInterest; } /** * @notice Function to get the token index * @param _token The address of the token * @return uint256 The index of the token */ function getTokenIndex(address _token) external view returns (uint256) { return whitelistedTokens[_token].tokenIndex; } /** * @notice Function to update the borrow start date partially for a DSA account * @param _connectorID The ID of the connector * @param _time The backed time * @param _dsaAddress The address of the DSA account * @param _token The address of the token */ function updateBorrowDate(uint256 _connectorID, uint256 _time, address _dsaAddress, address _token) external { address connector = getDoughConnector[_connectorID]; if (msg.sender != _dsaAddress && msg.sender != connector) revert CustomError("Invalid Caller"); // Check if the DSA is registered in the DoughIndex or not if (getOwnerOfDoughDsa[_dsaAddress] == address(0)) revert CustomError("Index DSA not found"); _dsaTokenBorrowStartDate[_dsaAddress][_token] = _time; emit UpdateBorrowDate(msg.sender, _dsaAddress, _token, _connectorID, _time); } /** * @notice Calculates the current interest for a given DSA account. * @param _token The address of the token. * @param _dsaAddress The address of the DSA account. * @return _scaledInterest The interest accrued since the last update. */ function borrowFormulaInterest (address _token, address _dsaAddress) external view returns (uint256 _scaledInterest) { return IBorrowManagementConnector(borrowFormulaAddress).borrowFormulaInterest(_token, _dsaAddress); } /** * @notice Calculates the current debt and interest for a given DSA account. * @param _token The address of the token. * @param _dsaAddress The address of the DSA account. * @return _debtAmount The current debt amount without interest. * @return _totalAmount The total debt amount including accrued interest. * @return _scaledInterest The interest accrued since the last update. * @return _minInterest The minimum interest amount for this token, for validation purposes. */ function borrowFormula (address _token, address _dsaAddress) external view returns (uint256 _debtAmount, uint256 _totalAmount, uint256 _scaledInterest, uint256 _minInterest) { (uint256 currentVariableDebt, uint256 totalAmount, uint256 scaledInterest, uint256 minInterest) = IBorrowManagementConnector(borrowFormulaAddress).borrowFormula(_token, _dsaAddress); return (currentVariableDebt, totalAmount, scaledInterest, minInterest); } /** * @dev Checks if an address is a smart contract * @param addr The address to check * @return bool true if `addr` is a smart contract, false otherwise */ function isContract(address addr) private view returns (bool) { uint32 size; assembly { size := extcodesize(addr) } return size > 0; } uint256[30] __gap; // Adjusted for new variable }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title IPool * @author Aave * @notice Defines the basic interface for an Aave Pool. */ interface IPool { /** * @dev Emitted on mintUnbacked() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens * @param amount The amount of supplied assets * @param referralCode The referral code used */ event MintUnbacked( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on backUnbacked() * @param reserve The address of the underlying asset of the reserve * @param backer The address paying for the backing * @param amount The amount added as backing * @param fee The amount paid in fees */ event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee); /** * @dev Emitted on supply() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the supply * @param onBehalfOf The beneficiary of the supply, receiving the aTokens * @param amount The amount supplied * @param referralCode The referral code used */ event Supply( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referralCode ); /** * @dev Emitted on withdraw() * @param reserve The address of the underlying asset being withdrawn * @param user The address initiating the withdrawal, owner of aTokens * @param to The address that will receive the underlying * @param amount The amount to be withdrawn */ event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); /** * @dev Emitted on borrow() and flashLoan() when debt needs to be opened * @param reserve The address of the underlying asset being borrowed * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just * initiator of the transaction on flashLoan() * @param onBehalfOf The address that will be getting the debt * @param amount The amount borrowed out * @param interestRateMode The rate mode: 1 for Stable, 2 for Variable * @param borrowRate The numeric rate at which the user has borrowed, expressed in ray * @param referralCode The referral code used */ event Borrow( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 borrowRate, uint16 indexed referralCode ); /** * @dev Emitted on repay() * @param reserve The address of the underlying asset of the reserve * @param user The beneficiary of the repayment, getting his debt reduced * @param repayer The address of the user initiating the repay(), providing the funds * @param amount The amount repaid * @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly */ event Repay( address indexed reserve, address indexed user, address indexed repayer, uint256 amount, bool useATokens ); /** * @dev Emitted on swapBorrowRateMode() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user swapping his rate mode * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable */ event SwapBorrowRateMode( address indexed reserve, address indexed user, DataTypes.InterestRateMode interestRateMode ); /** * @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets * @param asset The address of the underlying asset of the reserve * @param totalDebt The total isolation mode debt for the reserve */ event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); /** * @dev Emitted when the user selects a certain asset category for eMode * @param user The address of the user * @param categoryId The category id */ event UserEModeSet(address indexed user, uint8 categoryId); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral */ event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral */ event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); /** * @dev Emitted on rebalanceStableBorrowRate() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user for which the rebalance has been executed */ event RebalanceStableBorrowRate(address indexed reserve, address indexed user); /** * @dev Emitted on flashLoan() * @param target The address of the flash loan receiver contract * @param initiator The address initiating the flash loan * @param asset The address of the asset being flash borrowed * @param amount The amount flash borrowed * @param interestRateMode The flashloan mode: 0 for regular flashloan, 1 for Stable debt, 2 for Variable debt * @param premium The fee flash borrowed * @param referralCode The referral code used */ event FlashLoan( address indexed target, address initiator, address indexed asset, uint256 amount, DataTypes.InterestRateMode interestRateMode, uint256 premium, uint16 indexed referralCode ); /** * @dev Emitted when a borrower is liquidated. * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param liquidatedCollateralAmount The amount of collateral received by the liquidator * @param liquidator The address of the liquidator * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly */ event LiquidationCall( address indexed collateralAsset, address indexed debtAsset, address indexed user, uint256 debtToCover, uint256 liquidatedCollateralAmount, address liquidator, bool receiveAToken ); /** * @dev Emitted when the state of a reserve is updated. * @param reserve The address of the underlying asset of the reserve * @param liquidityRate The next liquidity rate * @param stableBorrowRate The next stable borrow rate * @param variableBorrowRate The next variable borrow rate * @param liquidityIndex The next liquidity index * @param variableBorrowIndex The next variable borrow index */ event ReserveDataUpdated( address indexed reserve, uint256 liquidityRate, uint256 stableBorrowRate, uint256 variableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex ); /** * @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest. * @param reserve The address of the reserve * @param amountMinted The amount minted to the treasury */ event MintedToTreasury(address indexed reserve, uint256 amountMinted); /** * @notice Mints an `amount` of aTokens to the `onBehalfOf` * @param asset The address of the underlying asset to mint * @param amount The amount to mint * @param onBehalfOf The address that will receive the aTokens * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function mintUnbacked( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; /** * @notice Back the current unbacked underlying with `amount` and pay `fee`. * @param asset The address of the underlying asset to back * @param amount The amount to back * @param fee The amount paid in fees * @return The backed amount */ function backUnbacked(address asset, uint256 amount, uint256 fee) external returns (uint256); /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; /** * @notice Supply with transfer approval of asset to be supplied done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param deadline The deadline timestamp that the permit is valid * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig */ function supplyWithPermit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external; /** * @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC * @param asset The address of the underlying asset to withdraw * @param amount The underlying amount to be withdrawn * - Send the value type(uint256).max in order to withdraw the whole aToken balance * @param to The address that will receive the underlying, same as msg.sender if the user * wants to receive it on his own wallet, or a different address if the beneficiary is a * different wallet * @return The final amount withdrawn */ function withdraw(address asset, uint256 amount, address to) external returns (uint256); /** * @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower * already supplied enough collateral, or he was given enough allowance by a credit delegator on the * corresponding debt token (StableDebtToken or VariableDebtToken) * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet * and 100 stable/variable debt tokens, depending on the `interestRateMode` * @param asset The address of the underlying asset to borrow * @param amount The amount to be borrowed * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator * if he has been given credit delegation allowance */ function borrow( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf ) external; /** * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @return The final amount repaid */ function repay( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf ) external returns (uint256); /** * @notice Repay with transfer approval of asset to be repaid done via permit function * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @param deadline The deadline timestamp that the permit is valid * @param permitV The V parameter of ERC712 permit sig * @param permitR The R parameter of ERC712 permit sig * @param permitS The S parameter of ERC712 permit sig * @return The final amount repaid */ function repayWithPermit( address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS ) external returns (uint256); /** * @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the * equivalent debt tokens * - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable/stable debt tokens * @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken * balance is not enough to cover the whole debt * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @return The final amount repaid */ function repayWithATokens( address asset, uint256 amount, uint256 interestRateMode ) external returns (uint256); /** * @notice Allows a borrower to swap his debt between stable and variable mode, or vice versa * @param asset The address of the underlying asset borrowed * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable */ function swapBorrowRateMode(address asset, uint256 interestRateMode) external; /** * @notice Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. * - Users can be rebalanced if the following conditions are satisfied: * 1. Usage ratio is above 95% * 2. the current supply APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too * much has been borrowed at a stable rate and suppliers are not earning enough * @param asset The address of the underlying asset borrowed * @param user The address of the user to be rebalanced */ function rebalanceStableBorrowRate(address asset, address user) external; /** * @notice Allows suppliers to enable/disable a specific supplied asset as collateral * @param asset The address of the underlying asset supplied * @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise */ function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; /** * @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly */ function liquidationCall( address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface * @param assets The addresses of the assets being flash-borrowed * @param amounts The amounts of the assets being flash-borrowed * @param interestRateModes Types of the debt to open if the flash loan is not returned: * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver * 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2 * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function flashLoan( address receiverAddress, address[] calldata assets, uint256[] calldata amounts, uint256[] calldata interestRateModes, address onBehalfOf, bytes calldata params, uint16 referralCode ) external; /** * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept * into consideration. For further details please visit https://docs.aave.com/developers/ * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface * @param asset The address of the asset being flash-borrowed * @param amount The amount of the asset being flash-borrowed * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode The code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function flashLoanSimple( address receiverAddress, address asset, uint256 amount, bytes calldata params, uint16 referralCode ) external; /** * @notice Returns the user account data across all the reserves * @param user The address of the user * @return totalCollateralBase The total collateral of the user in the base currency used by the price feed * @return totalDebtBase The total debt of the user in the base currency used by the price feed * @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed * @return currentLiquidationThreshold The liquidation threshold of the user * @return ltv The loan to value of The user * @return healthFactor The current health factor of the user */ function getUserAccountData( address user ) external view returns ( uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); /** * @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an * interest rate strategy * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param aTokenAddress The address of the aToken that will be assigned to the reserve * @param stableDebtAddress The address of the StableDebtToken that will be assigned to the reserve * @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve * @param interestRateStrategyAddress The address of the interest rate strategy contract */ function initReserve( address asset, address aTokenAddress, address stableDebtAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; /** * @notice Drop a reserve * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve */ function dropReserve(address asset) external; /** * @notice Updates the address of the interest rate strategy contract * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param rateStrategyAddress The address of the interest rate strategy contract */ function setReserveInterestRateStrategyAddress( address asset, address rateStrategyAddress ) external; /** * @notice Sets the configuration bitmap of the reserve as a whole * @dev Only callable by the PoolConfigurator contract * @param asset The address of the underlying asset of the reserve * @param configuration The new configuration bitmap */ function setConfiguration( address asset, DataTypes.ReserveConfigurationMap calldata configuration ) external; /** * @notice Returns the configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The configuration of the reserve */ function getConfiguration( address asset ) external view returns (DataTypes.ReserveConfigurationMap memory); /** * @notice Returns the configuration of the user across all the reserves * @param user The user address * @return The configuration of the user */ function getUserConfiguration( address user ) external view returns (DataTypes.UserConfigurationMap memory); /** * @notice Returns the normalized income of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve's normalized income */ function getReserveNormalizedIncome(address asset) external view returns (uint256); /** * @notice Returns the normalized variable debt per unit of asset * @dev WARNING: This function is intended to be used primarily by the protocol itself to get a * "dynamic" variable index based on time, current stored index and virtual rate at the current * moment (approx. a borrower would get if opening a position). This means that is always used in * combination with variable debt supply/balances. * If using this function externally, consider that is possible to have an increasing normalized * variable debt that is not equivalent to how the variable debt index would be updated in storage * (e.g. only updates with non-zero variable debt supply) * @param asset The address of the underlying asset of the reserve * @return The reserve normalized variable debt */ function getReserveNormalizedVariableDebt(address asset) external view returns (uint256); /** * @notice Returns the state and configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The state and configuration data of the reserve */ function getReserveData(address asset) external view returns (DataTypes.ReserveData memory); /** * @notice Validates and finalizes an aToken transfer * @dev Only callable by the overlying aToken of the `asset` * @param asset The address of the underlying asset of the aToken * @param from The user from which the aTokens are transferred * @param to The user receiving the aTokens * @param amount The amount being transferred/withdrawn * @param balanceFromBefore The aToken balance of the `from` user before the transfer * @param balanceToBefore The aToken balance of the `to` user before the transfer */ function finalizeTransfer( address asset, address from, address to, uint256 amount, uint256 balanceFromBefore, uint256 balanceToBefore ) external; /** * @notice Returns the list of the underlying assets of all the initialized reserves * @dev It does not include dropped reserves * @return The addresses of the underlying assets of the initialized reserves */ function getReservesList() external view returns (address[] memory); /** * @notice Returns the address of the underlying asset of a reserve by the reserve id as stored in the DataTypes.ReserveData struct * @param id The id of the reserve as stored in the DataTypes.ReserveData struct * @return The address of the reserve associated with id */ function getReserveAddressById(uint16 id) external view returns (address); /** * @notice Returns the PoolAddressesProvider connected to this contract * @return The address of the PoolAddressesProvider */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Updates the protocol fee on the bridging * @param bridgeProtocolFee The part of the premium sent to the protocol treasury */ function updateBridgeProtocolFee(uint256 bridgeProtocolFee) external; /** * @notice Updates flash loan premiums. Flash loan premium consists of two parts: * - A part is sent to aToken holders as extra, one time accumulated interest * - A part is collected by the protocol treasury * @dev The total premium is calculated on the total borrowed amount * @dev The premium to protocol is calculated on the total premium, being a percentage of `flashLoanPremiumTotal` * @dev Only callable by the PoolConfigurator contract * @param flashLoanPremiumTotal The total premium, expressed in bps * @param flashLoanPremiumToProtocol The part of the premium sent to the protocol treasury, expressed in bps */ function updateFlashloanPremiums( uint128 flashLoanPremiumTotal, uint128 flashLoanPremiumToProtocol ) external; /** * @notice Configures a new category for the eMode. * @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category. * The category 0 is reserved as it's the default for volatile assets * @param id The id of the category * @param config The configuration of the category */ function configureEModeCategory(uint8 id, DataTypes.EModeCategory memory config) external; /** * @notice Returns the data of an eMode category * @param id The id of the category * @return The configuration data of the category */ function getEModeCategoryData(uint8 id) external view returns (DataTypes.EModeCategory memory); /** * @notice Allows a user to use the protocol in eMode * @param categoryId The id of the category */ function setUserEMode(uint8 categoryId) external; /** * @notice Returns the eMode the user is using * @param user The address of the user * @return The eMode id */ function getUserEMode(address user) external view returns (uint256); /** * @notice Resets the isolation mode total debt of the given asset to zero * @dev It requires the given asset has zero debt ceiling * @param asset The address of the underlying asset to reset the isolationModeTotalDebt */ function resetIsolationModeTotalDebt(address asset) external; /** * @notice Returns the percentage of available liquidity that can be borrowed at once at stable rate * @return The percentage of available liquidity to borrow, expressed in bps */ function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() external view returns (uint256); /** * @notice Returns the total fee on flash loans * @return The total fee on flashloans */ function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128); /** * @notice Returns the part of the bridge fees sent to protocol * @return The bridge fee sent to the protocol treasury */ function BRIDGE_PROTOCOL_FEE() external view returns (uint256); /** * @notice Returns the part of the flashloan fees sent to protocol * @return The flashloan fee sent to the protocol treasury */ function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128); /** * @notice Returns the maximum number of reserves supported to be listed in this Pool * @return The maximum number of reserves supported */ function MAX_NUMBER_RESERVES() external view returns (uint16); /** * @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens * @param assets The list of reserves for which the minting needs to be executed */ function mintToTreasury(address[] calldata assets) external; /** * @notice Rescue and transfer tokens locked in this contract * @param token The address of the token * @param to The address of the recipient * @param amount The amount of token to transfer */ function rescueTokens(address token, address to, uint256 amount) external; /** * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User supplies 100 USDC and gets in return 100 aUSDC * @dev Deprecated: Use the `supply` function instead * @param asset The address of the underlying asset to supply * @param amount The amount to be supplied * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man */ function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; /** * @title IPoolAddressesProvider * @author Aave * @notice Defines the basic interface for a Pool Addresses Provider. */ interface IPoolAddressesProvider { /** * @dev Emitted when the market identifier is updated. * @param oldMarketId The old id of the market * @param newMarketId The new id of the market */ event MarketIdSet(string indexed oldMarketId, string indexed newMarketId); /** * @dev Emitted when the pool is updated. * @param oldAddress The old address of the Pool * @param newAddress The new address of the Pool */ event PoolUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the pool configurator is updated. * @param oldAddress The old address of the PoolConfigurator * @param newAddress The new address of the PoolConfigurator */ event PoolConfiguratorUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the price oracle is updated. * @param oldAddress The old address of the PriceOracle * @param newAddress The new address of the PriceOracle */ event PriceOracleUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the ACL manager is updated. * @param oldAddress The old address of the ACLManager * @param newAddress The new address of the ACLManager */ event ACLManagerUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the ACL admin is updated. * @param oldAddress The old address of the ACLAdmin * @param newAddress The new address of the ACLAdmin */ event ACLAdminUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the price oracle sentinel is updated. * @param oldAddress The old address of the PriceOracleSentinel * @param newAddress The new address of the PriceOracleSentinel */ event PriceOracleSentinelUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the pool data provider is updated. * @param oldAddress The old address of the PoolDataProvider * @param newAddress The new address of the PoolDataProvider */ event PoolDataProviderUpdated(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when a new proxy is created. * @param id The identifier of the proxy * @param proxyAddress The address of the created proxy contract * @param implementationAddress The address of the implementation contract */ event ProxyCreated( bytes32 indexed id, address indexed proxyAddress, address indexed implementationAddress ); /** * @dev Emitted when a new non-proxied contract address is registered. * @param id The identifier of the contract * @param oldAddress The address of the old contract * @param newAddress The address of the new contract */ event AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when the implementation of the proxy registered with id is updated * @param id The identifier of the contract * @param proxyAddress The address of the proxy contract * @param oldImplementationAddress The address of the old implementation contract * @param newImplementationAddress The address of the new implementation contract */ event AddressSetAsProxy( bytes32 indexed id, address indexed proxyAddress, address oldImplementationAddress, address indexed newImplementationAddress ); /** * @notice Returns the id of the Aave market to which this contract points to. * @return The market id */ function getMarketId() external view returns (string memory); /** * @notice Associates an id with a specific PoolAddressesProvider. * @dev This can be used to create an onchain registry of PoolAddressesProviders to * identify and validate multiple Aave markets. * @param newMarketId The market id */ function setMarketId(string calldata newMarketId) external; /** * @notice Returns an address by its identifier. * @dev The returned address might be an EOA or a contract, potentially proxied * @dev It returns ZERO if there is no registered address with the given id * @param id The id * @return The address of the registered for the specified id */ function getAddress(bytes32 id) external view returns (address); /** * @notice General function to update the implementation of a proxy registered with * certain `id`. If there is no proxy registered, it will instantiate one and * set as implementation the `newImplementationAddress`. * @dev IMPORTANT Use this function carefully, only for ids that don't have an explicit * setter function, in order to avoid unexpected consequences * @param id The id * @param newImplementationAddress The address of the new implementation */ function setAddressAsProxy(bytes32 id, address newImplementationAddress) external; /** * @notice Sets an address for an id replacing the address saved in the addresses map. * @dev IMPORTANT Use this function carefully, as it will do a hard replacement * @param id The id * @param newAddress The address to set */ function setAddress(bytes32 id, address newAddress) external; /** * @notice Returns the address of the Pool proxy. * @return The Pool proxy address */ function getPool() external view returns (address); /** * @notice Updates the implementation of the Pool, or creates a proxy * setting the new `pool` implementation when the function is called for the first time. * @param newPoolImpl The new Pool implementation */ function setPoolImpl(address newPoolImpl) external; /** * @notice Returns the address of the PoolConfigurator proxy. * @return The PoolConfigurator proxy address */ function getPoolConfigurator() external view returns (address); /** * @notice Updates the implementation of the PoolConfigurator, or creates a proxy * setting the new `PoolConfigurator` implementation when the function is called for the first time. * @param newPoolConfiguratorImpl The new PoolConfigurator implementation */ function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external; /** * @notice Returns the address of the price oracle. * @return The address of the PriceOracle */ function getPriceOracle() external view returns (address); /** * @notice Updates the address of the price oracle. * @param newPriceOracle The address of the new PriceOracle */ function setPriceOracle(address newPriceOracle) external; /** * @notice Returns the address of the ACL manager. * @return The address of the ACLManager */ function getACLManager() external view returns (address); /** * @notice Updates the address of the ACL manager. * @param newAclManager The address of the new ACLManager */ function setACLManager(address newAclManager) external; /** * @notice Returns the address of the ACL admin. * @return The address of the ACL admin */ function getACLAdmin() external view returns (address); /** * @notice Updates the address of the ACL admin. * @param newAclAdmin The address of the new ACL admin */ function setACLAdmin(address newAclAdmin) external; /** * @notice Returns the address of the price oracle sentinel. * @return The address of the PriceOracleSentinel */ function getPriceOracleSentinel() external view returns (address); /** * @notice Updates the address of the price oracle sentinel. * @param newPriceOracleSentinel The address of the new PriceOracleSentinel */ function setPriceOracleSentinel(address newPriceOracleSentinel) external; /** * @notice Returns the address of the data provider. * @return The address of the DataProvider */ function getPoolDataProvider() external view returns (address); /** * @notice Updates the address of the data provider. * @param newDataProvider The address of the new DataProvider */ function setPoolDataProvider(address newDataProvider) external; }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; /** * @title IPoolDataProvider * @author Aave * @notice Defines the basic interface of a PoolDataProvider */ interface IPoolDataProvider { struct TokenData { string symbol; address tokenAddress; } /** * @notice Returns the address for the PoolAddressesProvider contract. * @return The address for the PoolAddressesProvider contract */ function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice Returns the list of the existing reserves in the pool. * @dev Handling MKR and ETH in a different way since they do not have standard `symbol` functions. * @return The list of reserves, pairs of symbols and addresses */ function getAllReservesTokens() external view returns (TokenData[] memory); /** * @notice Returns the list of the existing ATokens in the pool. * @return The list of ATokens, pairs of symbols and addresses */ function getAllATokens() external view returns (TokenData[] memory); /** * @notice Returns the configuration data of the reserve * @dev Not returning borrow and supply caps for compatibility, nor pause flag * @param asset The address of the underlying asset of the reserve * @return decimals The number of decimals of the reserve * @return ltv The ltv of the reserve * @return liquidationThreshold The liquidationThreshold of the reserve * @return liquidationBonus The liquidationBonus of the reserve * @return reserveFactor The reserveFactor of the reserve * @return usageAsCollateralEnabled True if the usage as collateral is enabled, false otherwise * @return borrowingEnabled True if borrowing is enabled, false otherwise * @return stableBorrowRateEnabled True if stable rate borrowing is enabled, false otherwise * @return isActive True if it is active, false otherwise * @return isFrozen True if it is frozen, false otherwise */ 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 ); /** * @notice Returns the efficiency mode category of the reserve * @param asset The address of the underlying asset of the reserve * @return The eMode id of the reserve */ function getReserveEModeCategory(address asset) external view returns (uint256); /** * @notice Returns the caps parameters of the reserve * @param asset The address of the underlying asset of the reserve * @return borrowCap The borrow cap of the reserve * @return supplyCap The supply cap of the reserve */ function getReserveCaps( address asset ) external view returns (uint256 borrowCap, uint256 supplyCap); /** * @notice Returns if the pool is paused * @param asset The address of the underlying asset of the reserve * @return isPaused True if the pool is paused, false otherwise */ function getPaused(address asset) external view returns (bool isPaused); /** * @notice Returns the siloed borrowing flag * @param asset The address of the underlying asset of the reserve * @return True if the asset is siloed for borrowing */ function getSiloedBorrowing(address asset) external view returns (bool); /** * @notice Returns the protocol fee on the liquidation bonus * @param asset The address of the underlying asset of the reserve * @return The protocol fee on liquidation */ function getLiquidationProtocolFee(address asset) external view returns (uint256); /** * @notice Returns the unbacked mint cap of the reserve * @param asset The address of the underlying asset of the reserve * @return The unbacked mint cap of the reserve */ function getUnbackedMintCap(address asset) external view returns (uint256); /** * @notice Returns the debt ceiling of the reserve * @param asset The address of the underlying asset of the reserve * @return The debt ceiling of the reserve */ function getDebtCeiling(address asset) external view returns (uint256); /** * @notice Returns the debt ceiling decimals * @return The debt ceiling decimals */ function getDebtCeilingDecimals() external pure returns (uint256); /** * @notice Returns the reserve data * @param asset The address of the underlying asset of the reserve * @return unbacked The amount of unbacked tokens * @return accruedToTreasuryScaled The scaled amount of tokens accrued to treasury that is to be minted * @return totalAToken The total supply of the aToken * @return totalStableDebt The total stable debt of the reserve * @return totalVariableDebt The total variable debt of the reserve * @return liquidityRate The liquidity rate of the reserve * @return variableBorrowRate The variable borrow rate of the reserve * @return stableBorrowRate The stable borrow rate of the reserve * @return averageStableBorrowRate The average stable borrow rate of the reserve * @return liquidityIndex The liquidity index of the reserve * @return variableBorrowIndex The variable borrow index of the reserve * @return lastUpdateTimestamp The timestamp of the last update of the reserve */ function getReserveData( address asset ) external view returns ( uint256 unbacked, uint256 accruedToTreasuryScaled, uint256 totalAToken, uint256 totalStableDebt, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, uint256 averageStableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp ); /** * @notice Returns the total supply of aTokens for a given asset * @param asset The address of the underlying asset of the reserve * @return The total supply of the aToken */ function getATokenTotalSupply(address asset) external view returns (uint256); /** * @notice Returns the total debt for a given asset * @param asset The address of the underlying asset of the reserve * @return The total debt for asset */ function getTotalDebt(address asset) external view returns (uint256); /** * @notice Returns the user data in a reserve * @param asset The address of the underlying asset of the reserve * @param user The address of the user * @return currentATokenBalance The current AToken balance of the user * @return currentStableDebt The current stable debt of the user * @return currentVariableDebt The current variable debt of the user * @return principalStableDebt The principal stable debt of the user * @return scaledVariableDebt The scaled variable debt of the user * @return stableBorrowRate The stable borrow rate of the user * @return liquidityRate The liquidity rate of the reserve * @return stableRateLastUpdated The timestamp of the last update of the user stable rate * @return usageAsCollateralEnabled True if the user is using the asset as collateral, false * otherwise */ 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 ); /** * @notice Returns the token addresses of the reserve * @param asset The address of the underlying asset of the reserve * @return aTokenAddress The AToken address of the reserve * @return stableDebtTokenAddress The StableDebtToken address of the reserve * @return variableDebtTokenAddress The VariableDebtToken address of the reserve */ function getReserveTokensAddresses( address asset ) external view returns ( address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress ); /** * @notice Returns the address of the Interest Rate strategy * @param asset The address of the underlying asset of the reserve * @return irStrategyAddress The address of the Interest Rate strategy */ function getInterestRateStrategyAddress( address asset ) external view returns (address irStrategyAddress); /** * @notice Returns whether the reserve has FlashLoans enabled or disabled * @param asset The address of the underlying asset of the reserve * @return True if FlashLoans are enabled, false otherwise */ function getFlashLoanEnabled(address asset) external view returns (bool); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library DataTypes { struct ReserveData { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; //the current stable borrow rate. Expressed in ray uint128 currentStableBorrowRate; //timestamp of last update uint40 lastUpdateTimestamp; //the id of the reserve. Represents the position in the list of the active reserves uint16 id; //aToken address address aTokenAddress; //stableDebtToken address address stableDebtTokenAddress; //variableDebtToken address address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the current treasury balance, scaled uint128 accruedToTreasury; //the outstanding unbacked aTokens minted through the bridging feature uint128 unbacked; //the outstanding debt borrowed against this asset in isolation mode uint128 isolationModeTotalDebt; } struct ReserveConfigurationMap { //bit 0-15: LTV //bit 16-31: Liq. threshold //bit 32-47: Liq. bonus //bit 48-55: Decimals //bit 56: reserve is active //bit 57: reserve is frozen //bit 58: borrowing is enabled //bit 59: stable rate borrowing enabled //bit 60: asset is paused //bit 61: borrowing in isolation mode is enabled //bit 62: siloed borrowing enabled //bit 63: flashloaning enabled //bit 64-79: reserve factor //bit 80-115 borrow cap in whole tokens, borrowCap == 0 => no cap //bit 116-151 supply cap in whole tokens, supplyCap == 0 => no cap //bit 152-167 liquidation protocol fee //bit 168-175 eMode category //bit 176-211 unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled //bit 212-251 debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals //bit 252-255 unused uint256 data; } struct UserConfigurationMap { /** * @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset. * The first bit indicates if an asset is used as collateral by the user, the second whether an * asset is borrowed by the user. */ uint256 data; } struct EModeCategory { // each eMode category has a custom ltv and liquidation threshold uint16 ltv; uint16 liquidationThreshold; uint16 liquidationBonus; // each eMode category may or may not have a custom oracle to override the individual assets price oracles address priceSource; string label; } enum InterestRateMode {NONE, STABLE, VARIABLE} struct ReserveCache { uint256 currScaledVariableDebt; uint256 nextScaledVariableDebt; uint256 currPrincipalStableDebt; uint256 currAvgStableBorrowRate; uint256 currTotalStableDebt; uint256 nextAvgStableBorrowRate; uint256 nextTotalStableDebt; uint256 currLiquidityIndex; uint256 nextLiquidityIndex; uint256 currVariableBorrowIndex; uint256 nextVariableBorrowIndex; uint256 currLiquidityRate; uint256 currVariableBorrowRate; uint256 reserveFactor; ReserveConfigurationMap reserveConfiguration; address aTokenAddress; address stableDebtTokenAddress; address variableDebtTokenAddress; uint40 reserveLastUpdateTimestamp; uint40 stableDebtLastUpdateTimestamp; } struct ExecuteLiquidationCallParams { uint256 reservesCount; uint256 debtToCover; address collateralAsset; address debtAsset; address user; bool receiveAToken; address priceOracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteSupplyParams { address asset; uint256 amount; address onBehalfOf; uint16 referralCode; } struct ExecuteBorrowParams { address asset; address user; address onBehalfOf; uint256 amount; InterestRateMode interestRateMode; uint16 referralCode; bool releaseUnderlying; uint256 maxStableRateBorrowSizePercent; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; } struct ExecuteRepayParams { address asset; uint256 amount; InterestRateMode interestRateMode; address onBehalfOf; bool useATokens; } struct ExecuteWithdrawParams { address asset; uint256 amount; address to; uint256 reservesCount; address oracle; uint8 userEModeCategory; } struct ExecuteSetUserEModeParams { uint256 reservesCount; address oracle; uint8 categoryId; } struct FinalizeTransferParams { address asset; address from; address to; uint256 amount; uint256 balanceFromBefore; uint256 balanceToBefore; uint256 reservesCount; address oracle; uint8 fromEModeCategory; } struct FlashloanParams { address receiverAddress; address[] assets; uint256[] amounts; uint256[] interestRateModes; address onBehalfOf; bytes params; uint16 referralCode; uint256 flashLoanPremiumToProtocol; uint256 flashLoanPremiumTotal; uint256 maxStableRateBorrowSizePercent; uint256 reservesCount; address addressesProvider; uint8 userEModeCategory; bool isAuthorizedFlashBorrower; } struct FlashloanSimpleParams { address receiverAddress; address asset; uint256 amount; bytes params; uint16 referralCode; uint256 flashLoanPremiumToProtocol; uint256 flashLoanPremiumTotal; } struct FlashLoanRepaymentParams { uint256 amount; uint256 totalPremium; uint256 flashLoanPremiumToProtocol; address asset; address receiverAddress; uint16 referralCode; } struct CalculateUserAccountDataParams { UserConfigurationMap userConfig; uint256 reservesCount; address user; address oracle; uint8 userEModeCategory; } struct ValidateBorrowParams { ReserveCache reserveCache; UserConfigurationMap userConfig; address asset; address userAddress; uint256 amount; InterestRateMode interestRateMode; uint256 maxStableLoanPercent; uint256 reservesCount; address oracle; uint8 userEModeCategory; address priceOracleSentinel; bool isolationModeActive; address isolationModeCollateralAddress; uint256 isolationModeDebtCeiling; } struct ValidateLiquidationCallParams { ReserveCache debtReserveCache; uint256 totalDebt; uint256 healthFactor; address priceOracleSentinel; } struct CalculateInterestRatesParams { uint256 unbacked; uint256 liquidityAdded; uint256 liquidityTaken; uint256 totalStableDebt; uint256 totalVariableDebt; uint256 averageStableBorrowRate; uint256 reserveFactor; address reserve; address aToken; } struct InitReserveParams { address asset; address aTokenAddress; address stableDebtAddress; address variableDebtAddress; address interestRateStrategyAddress; uint16 reservesCount; uint16 maxNumberReserves; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.20; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._initialized = 1; if (isTopLevelCall) { $._initializing = true; } _; if (isTopLevelCall) { $._initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._initialized = version; $._initializing = true; _; $._initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/Clones.sol) pragma solidity ^0.8.20; /** * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for * deploying minimal proxy contracts, also known as "clones". * * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies * > a minimal bytecode implementation that delegates all calls to a known, fixed address. * * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the * deterministic method. */ library Clones { /** * @dev A clone instance deployment failed. */ error ERC1167FailedCreateClone(); /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create opcode, which should never revert. */ function clone(address implementation) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create(0, 0x09, 0x37) } if (instance == address(0)) { revert ERC1167FailedCreateClone(); } } /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create2 opcode and a `salt` to deterministically deploy * the clone. Using the same `implementation` and `salt` multiple time will revert, since * the clones cannot be deployed twice at the same address. */ function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create2(0, 0x09, 0x37, salt) } if (instance == address(0)) { revert ERC1167FailedCreateClone(); } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(add(ptr, 0x38), deployer) mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff) mstore(add(ptr, 0x14), implementation) mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73) mstore(add(ptr, 0x58), salt) mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37)) predicted := keccak256(add(ptr, 0x43), 0x55) } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt ) internal view returns (address predicted) { return predictDeterministicAddress(implementation, salt, address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC20Permit} from "../extensions/IERC20Permit.sol"; import {Address} from "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev An operation with an ERC20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Callback for IUniswapV3PoolActions#swap /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface interface IUniswapV3SwapCallback { /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. /// @dev In the implementation you must pay the pool tokens owed for the swap. /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call function uniswapV3SwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; /// @title Quoter Interface /// @notice Supports quoting the calculated amounts from exact input or exact output swaps /// @dev These functions are not marked view because they rely on calling non-view functions and reverting /// to compute the result. They are also not gas efficient and should not be called on-chain. interface IQuoter { /// @notice Returns the amount out received for a given exact input swap without executing the swap /// @param path The path of the swap, i.e. each token pair and the pool fee /// @param amountIn The amount of the first token to swap /// @return amountOut The amount of the last token that would be received function quoteExactInput(bytes memory path, uint256 amountIn) external returns (uint256 amountOut); /// @notice Returns the amount out received for a given exact input but for a swap of a single pool /// @param tokenIn The token being swapped in /// @param tokenOut The token being swapped out /// @param fee The fee of the token pool to consider for the pair /// @param amountIn The desired input amount /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap /// @return amountOut The amount of `tokenOut` that would be received function quoteExactInputSingle( address tokenIn, address tokenOut, uint24 fee, uint256 amountIn, uint160 sqrtPriceLimitX96 ) external returns (uint256 amountOut); /// @notice Returns the amount in required for a given exact output swap without executing the swap /// @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order /// @param amountOut The amount of the last token to receive /// @return amountIn The amount of first token required to be paid function quoteExactOutput(bytes memory path, uint256 amountOut) external returns (uint256 amountIn); /// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool /// @param tokenIn The token being swapped in /// @param tokenOut The token being swapped out /// @param fee The fee of the token pool to consider for the pair /// @param amountOut The desired output amount /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap /// @return amountIn The amount required as the input for the swap in order to receive `amountOut` function quoteExactOutputSingle( address tokenIn, address tokenOut, uint24 fee, uint256 amountOut, uint160 sqrtPriceLimitX96 ) external returns (uint256 amountIn); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol'; /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface ISwapRouter is IUniswapV3SwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata /// @return amountIn The amount of the input token function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.8.24; import { IDoughIndex, CustomError } from "./Interfaces.sol"; /** * $$$$$$$\ $$\ $$$$$$$$\ $$\ * $$ __$$\ $$ | $$ _____|\__| * $$ | $$ | $$$$$$\ $$\ $$\ $$$$$$\ $$$$$$$\ $$ | $$\ $$$$$$$\ $$$$$$\ $$$$$$$\ $$$$$$$\ $$$$$$\ * $$ | $$ |$$ __$$\ $$ | $$ |$$ __$$\ $$ __$$\ $$$$$\ $$ |$$ __$$\ \____$$\ $$ __$$\ $$ _____|$$ __$$\ * $$ | $$ |$$ / $$ |$$ | $$ |$$ / $$ |$$ | $$ | $$ __| $$ |$$ | $$ | $$$$$$$ |$$ | $$ |$$ / $$$$$$$$ | * $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ | $$ | $$ |$$ | $$ |$$ __$$ |$$ | $$ |$$ | $$ ____| * $$$$$$$ |\$$$$$$ |\$$$$$$ |\$$$$$$$ |$$ | $$ | $$ | $$ |$$ | $$ |\$$$$$$$ |$$ | $$ |\$$$$$$$\ \$$$$$$$\ * \_______/ \______/ \______/ \____$$ |\__| \__| \__| \__|\__| \__| \_______|\__| \__| \_______| \_______| * $$\ $$ | * \$$$$$$ | * \______/ * * @title DoughDsa * @notice This contract is used to delegate the call to the respective connectors * @custom:version 1.0 - Initial release * @author Liberalite https://github.com/liberalite * @custom:coauthor 0xboga https://github.com/0xboga */ contract DoughDsa { /* ========== LAYOUT ========== */ address public dsaOwner; address public doughIndex; /** * @notice Initializes the DoughDsa contract * @param _dsaOwner: The DSA owner address of the DSA contract * @param _doughIndex: The DoughIndex contract address */ function initialize(address _dsaOwner, address _doughIndex) external { if (dsaOwner != address(0) || _dsaOwner == address(0)) revert CustomError("invalid dsaOwner"); if (doughIndex != address(0) || _doughIndex == address(0)) revert CustomError("invalid doughIndex"); doughIndex = _doughIndex; dsaOwner = _dsaOwner; } /** * @notice Delegates the call to the respective connector * @param _connectorId: The connector ID to call * @param _actionId: The action ID to call * @param _token: The token address to call * @param _amount: The amount to call * @param _opt: The optional boolean value * @param _swapData: The swap data to call */ function doughCall(uint256 _connectorId, uint256 _actionId, address _token, uint256 _amount, bool _opt, bytes[] calldata _swapData) external payable { // _connectorId: 0-dsa 1-aave 2-paraswap 3-uniV3 4-deleveraging-uniV3 4-deleveraging-paraswap 5-shield 6-vault address _contract = IDoughIndex(doughIndex).getDoughConnector(_connectorId); if (_contract == address(0)) revert CustomError("Unregistered Connector"); if (_connectorId < 21) { // only the DSA Owner can run supply, withdraw, repay, swap, loop, deloop, etc if (msg.sender != dsaOwner) revert CustomError("Caller not dsaOwner"); } else if (_connectorId == 21 || _connectorId == 22) { if (msg.sender != IDoughIndex(doughIndex).deleverageAutomation()) revert CustomError("Only Deleveraging Automation"); } else if (_connectorId == 23) { if (msg.sender != IDoughIndex(doughIndex).shieldAutomation()) revert CustomError("Only Shield Automation"); } else if (_connectorId == 24) { if (msg.sender != IDoughIndex(doughIndex).vaultAutomation()) revert CustomError("Only Vault Automation"); } else { // future connectors will only be available to the DSA Owner if (msg.sender != dsaOwner) revert CustomError("Caller not dsaOwner"); } (bool success, bytes memory data) = _contract.delegatecall(abi.encodeWithSignature("delegateDoughCall(uint256,address,uint256,bool,bytes[])", _actionId, _token, _amount, _opt, _swapData)); if (!success) { if (data.length == 0) revert CustomError("Invalid doughcall error length"); if (data.length > 0) { assembly { revert(add(32, data), mload(data)) } } } } /** * @notice Executes an action from and to the Flashloan Connector * @param _connectorId: The connector ID * @param _tokenIn: The token address to get in * @param _inAmount: The amount to get in * @param _tokenOut: The token address to get out * @param _outAmount: The amount to get out * @param _actionId: The action ID to call */ function executeAction(uint256 _connectorId, address _tokenIn, uint256 _inAmount, address _tokenOut, uint256 _outAmount, uint256 _actionId) external payable { address _connector = IDoughIndex(doughIndex).getDoughConnector(_connectorId); if(msg.sender != address(this) && msg.sender != _connector) revert CustomError("Caller not owner or DSA"); address aaveActions = IDoughIndex(doughIndex).aaveActionsAddress(); (bool success, bytes memory data) = aaveActions.delegatecall(abi.encodeWithSignature("executeAaveAction(uint256,address,uint256,address,uint256,uint256)", _connectorId, _tokenIn, _inAmount, _tokenOut, _outAmount, _actionId)); if (!success) { if (data.length == 0) revert CustomError("Invalid Aave error length"); if (data.length > 0) { assembly { revert(add(32, data), mload(data)) } } } } /** * @notice allows DSA Owner to deposit and withdraw ETH */ receive() external payable {} fallback() external payable {} }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; error CustomError(string errorMsg); interface IWETH is IERC20 { function deposit() external payable; function withdraw(uint amount) external; } interface AaveActionsConnector { function executeAaveAction(address _dsaAddress, uint256 _connectorId, address _tokenIn, uint256 _inAmount, address _tokenOut, uint256 _outAmount, uint256 _actionId) external payable; } interface IDoughDsa { function doughCall(uint256 _connectorId, uint256 _actionId, address _token, uint256 _amount, bool _opt, bytes[] calldata _swapData) external payable; function executeAction(uint256 _connectorId, address tokenIn, uint256 inAmount, address tokenOut, uint256 outAmount, uint256 actionId) external payable; function dsaOwner() external view returns (address); function doughIndex() external view returns (address); } interface IDoughIndex { function aaveActionsAddress() external view returns (address); function setDsaMasterClone(address _dsaMasterCopy) external; function setNewBorrowFormula(address _newBorrowFormula) external; function setNewAaveActions(address _newAaveActions) external; function apyFee() external view returns (uint256); function getFlashBorrowers(address _flashBorrower) external view returns (bool); function deleverageAutomation() external view returns (address); function shieldAutomation() external view returns (address); function vaultAutomation() external view returns (address); function getWhitelistedTokenList() external view returns (address[] memory); function multisig() external view returns (address); function treasury() external view returns (address); function deleverageAsset() external view returns (address); function getDoughConnector (uint256 _connectorId) external view returns (address); function getOwnerOfDoughDsa(address dsaAddress) external view returns (address); function getDoughDsa(address dsaAddress) external view returns (address); function getTokenDecimals(address _token) external view returns (uint8); function getTokenMinInterest(address _token) external view returns (uint256); function getTokenIndex(address _token) external view returns (uint256); function borrowFormula (address _token, address _dsaAddress) external returns (uint256, uint256, uint256, uint256); function borrowFormulaInterest (address _token, address _dsaAddress) external returns (uint256); function getDsaBorrowStartDate (address _dsaAddress, address _token) external view returns (uint256); function updateBorrowDate(uint256 _connectorID, uint256 _time, address _dsaAddress, address _token) external; function minDeleveragingRatio() external view returns (uint256); function minHealthFactor() external view returns (uint256); } interface IBorrowManagementConnector { function borrowFormula(address _token, address _dsaAddress) external view returns (uint256, uint256, uint256, uint256); function borrowFormulaInterest(address _token, address _dsaAddress) external view returns (uint256); } interface IConnectorMultiFlashloan { function flashloanReq(address[] memory flashloanTokens, uint256[] memory flashloanAmounts, uint256[] memory flashLoanInterestRateModes, bytes[] memory swapData) external; } interface IConnectorMultiFlashloanOnchain { function flashloanReq(address[] memory flashloanTokens, uint256[] memory flashloanAmount, uint256[] memory flashLoanInterestRateModes, address[] memory flashLoanTokensCollateral, uint256[] memory flashLoanAmountsCollateral) external; } interface IConnectorFlashloan { function flashloanReq(address dsaOwnerAddress, address flashloanToken, uint256 flashloanAmount, uint256 flashActionId, bytes calldata _swapData) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.8.24; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@aave/core-v3/contracts/interfaces/IPoolDataProvider.sol"; import "@aave/core-v3/contracts/interfaces/IPool.sol"; import "@uniswap/v3-periphery/contracts/interfaces/IQuoter.sol"; import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol"; import { IWETH, IDoughIndex, CustomError } from "../Interfaces.sol"; /** * $$$$$$$\ $$\ $$$$$$$$\ $$\ * $$ __$$\ $$ | $$ _____|\__| * $$ | $$ | $$$$$$\ $$\ $$\ $$$$$$\ $$$$$$$\ $$ | $$\ $$$$$$$\ $$$$$$\ $$$$$$$\ $$$$$$$\ $$$$$$\ * $$ | $$ |$$ __$$\ $$ | $$ |$$ __$$\ $$ __$$\ $$$$$\ $$ |$$ __$$\ \____$$\ $$ __$$\ $$ _____|$$ __$$\ * $$ | $$ |$$ / $$ |$$ | $$ |$$ / $$ |$$ | $$ | $$ __| $$ |$$ | $$ | $$$$$$$ |$$ | $$ |$$ / $$$$$$$$ | * $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ | $$ | $$ |$$ | $$ |$$ __$$ |$$ | $$ |$$ | $$ ____| * $$$$$$$ |\$$$$$$ |\$$$$$$ |\$$$$$$$ |$$ | $$ | $$ | $$ |$$ | $$ |\$$$$$$$ |$$ | $$ |\$$$$$$$\ \$$$$$$$\ * \_______/ \______/ \______/ \____$$ |\__| \__| \__| \__|\__| \__| \_______|\__| \__| \_______| \_______| * $$\ $$ | * \$$$$$$ | * \______/ * * @title DoughCore * @notice The core contract for Dough Finance * @custom:version 1.0 - Initial release * @author Liberalite https://github.com/liberalite * @custom:coauthor 0xboga https://github.com/0xboga */ library DoughCore { using SafeERC20 for IERC20; // MAINNET uint256 public constant CHAIN_ID = 1; // TOKENS address public constant ADDRESS_ZERO = 0x0000000000000000000000000000000000000000; address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address public constant WBTC = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599; address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; address public constant LINK = 0x514910771AF9Ca656af840dff83E8264EcF986CA; address public constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; address public constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; // AAVE V3 CONFIG uint256 public constant FLASHLOAN_RATE_MODE = 0; // no borrow debt uint256 public constant VARIABLE_RATE_MODE = 2; // variable borrow rate // AAVE V3 ADDRESSES address public constant AAVE_V3_POOL_ADDRESS = 0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2; address public constant AAVE_V3_DATA_PROVIDER_ADDRESS = 0x7B4EB56E7CD4b454BA8ff71E4518426369a138a3; address public constant AAVE_V3_POOL_ADDRESS_PROVIDER = 0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e; // UNISWAP V2 address public constant UNISWAP_V2_ROUTER_ADDRESS = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; // UNISWAP V3 address public constant UNISWAP_V3_ROUTER_ADDRESS = 0xE592427A0AEce92De3Edee1F18E0157C05861564; address public constant UNISWAP_V3_QUOTER_ADDRESS = 0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6; // UNISWAP V3 INTERFACES ISwapRouter public constant _I_UNISWAP_V3_ROUTER = ISwapRouter(UNISWAP_V3_ROUTER_ADDRESS); IQuoter public constant _I_UNISWAP_V3_QUOTER = IQuoter(UNISWAP_V3_QUOTER_ADDRESS); // AAVE V3 INTERFACES IPool public constant _I_AAVE_V3_POOL = IPool(AAVE_V3_POOL_ADDRESS); IPoolDataProvider public constant _I_AAVE_V3_DATA_PROVIDER = IPoolDataProvider(AAVE_V3_DATA_PROVIDER_ADDRESS); // DOUGH CONNECTORS ID uint256 public constant CONNECTOR_ID0 = 0; uint256 public constant CONNECTOR_ID1 = 1; uint256 public constant CONNECTOR_ID2 = 2; uint256 public constant CONNECTOR_ID3 = 3; uint256 public constant CONNECTOR_ID4 = 4; uint256 public constant CONNECTOR_ID5 = 5; uint256 public constant CONNECTOR_ID6 = 6; uint256 public constant CONNECTOR_ID7 = 7; uint256 public constant CONNECTOR_ID8 = 8; uint256 public constant CONNECTOR_ID9 = 9; uint256 public constant CONNECTOR_ID10 = 10; uint256 public constant CONNECTOR_ID11 = 11; uint256 public constant CONNECTOR_ID12 = 12; uint256 public constant CONNECTOR_ID13 = 13; uint256 public constant CONNECTOR_ID14 = 14; uint256 public constant CONNECTOR_ID15 = 15; uint256 public constant CONNECTOR_ID16 = 16; uint256 public constant CONNECTOR_ID17 = 17; uint256 public constant CONNECTOR_ID18 = 18; uint256 public constant CONNECTOR_ID19 = 19; uint256 public constant CONNECTOR_ID20 = 20; uint256 public constant CONNECTOR_ID21 = 21; uint256 public constant CONNECTOR_ID22 = 22; uint256 public constant CONNECTOR_ID23 = 23; uint256 public constant CONNECTOR_ID24 = 24; uint256 public constant CONNECTOR_ID25 = 25; uint256 public constant CONNECTOR_ID26 = 26; uint256 public constant CONNECTOR_ID27 = 27; uint256 public constant CONNECTOR_ID28 = 28; uint256 public constant CONNECTOR_ID29 = 29; uint256 public constant CONNECTOR_ID30 = 30; uint256 public constant CONNECTOR_ID31 = 31; uint256 public constant CONNECTOR_ID32 = 32; uint256 public constant CONNECTOR_ID33 = 33; /** * @notice Function to repay AAVE V3 debt with Aave Tokens * @param _tokenIn The token address to repay the debt * @param _inAmount The amount of the token to repay the debt * @dev The token should be whitelisted in the DoughIndex contract */ function repayWithATokens(address _tokenIn, uint256 _inAmount) external { _I_AAVE_V3_POOL.repayWithATokens(_tokenIn, _inAmount, VARIABLE_RATE_MODE); } /** * @notice Collects the APY fees for all the whitelisted tokens * @param _doughIndex The DoughIndex address * @dev The APY fees are collected for all the whitelisted tokens */ function collectApyFees(address _doughIndex) external { // Check if the flash borrower is the caller if(IDoughIndex(_doughIndex).getFlashBorrowers(address(this))) return; // Get the whitelisted tokens address[] memory whitelistedTokens = IDoughIndex(_doughIndex).getWhitelistedTokenList(); // Iterate through the whitelisted tokens for (uint i = 0; i < whitelistedTokens.length;) { // Get the APY fees for the given token (, , uint256 scaledInterest, uint256 minInterest) = IDoughIndex(_doughIndex).borrowFormula(whitelistedTokens[i], address(this)); // Check if the scaled interest is greater than the minimum interest if (scaledInterest > minInterest) collectTreasuryFees(_doughIndex, address(this), whitelistedTokens[i], scaledInterest); // Increment the counter unchecked { i++; } } } /** * @notice Collects the APY fees for the given token if minimum interest is met * @param _doughIndex The DoughIndex address * @param _token: The whitelisted token address */ function collectAnyApyFees(address _doughIndex, address _token) external { // Check if the flash borrower is the caller if(IDoughIndex(_doughIndex).getFlashBorrowers(address(this))) return; // Get the APY fees for the given token (, , uint256 scaledInterest, uint256 minInterest) = IDoughIndex(_doughIndex).borrowFormula(_token, address(this)); // Check if the scaled interest is greater than the minimum interest if (scaledInterest > minInterest) collectTreasuryFees(_doughIndex, address(this), _token, scaledInterest); } /** * @notice Collects the APY fees for the given token * @param _doughIndex The DoughIndex address * @param _token: The whitelisted token address */ function collectApyFeesInterest(address _doughIndex, address _token) external { // Check if the flash borrower is the caller if(IDoughIndex(_doughIndex).getFlashBorrowers(address(this))) return; // Get the time when the borrowing started (uint256 scaledInterest) = IDoughIndex(_doughIndex).borrowFormulaInterest(_token, address(this)); // Check if the scaled interest is greater than 0 if (scaledInterest > 0) collectTreasuryFees(_doughIndex, address(this), _token, scaledInterest); } /** * @notice Collects the APY fees for the given token partially * @param _doughIndex The DoughIndex address * @param _token: The whitelisted token address * @param _partialAmount The partial amount of APY fees */ function collectApyFeesPartially(address _doughIndex, address _token, uint256 _partialAmount) private { // Check if the flash borrower is the caller if(IDoughIndex(_doughIndex).getFlashBorrowers(address(this))) return; // Get the time when the borrowing started uint256 timeStartedBorrow = IDoughIndex(_doughIndex).getDsaBorrowStartDate(address(this), _token); // Get the scaled interest for the given token (uint256 scaledInterest) = IDoughIndex(_doughIndex).borrowFormulaInterest(_token, address(this)); // Check if the partial amount is greater than the scaled interest if (_partialAmount > scaledInterest) revert CustomError("partialAmount >= scaled interest"); // Calculate the time difference between the current time and the time when the borrowing started uint256 timeDiff = block.timestamp - timeStartedBorrow; // Calculate the APY fees per second uint256 perSecond = scaledInterest / timeDiff; // Check if the perSecond is 0 if (perSecond == 0) revert CustomError("perSecond is 0"); // Calculate the back time in seconds uint256 backTimeInSeconds = (_partialAmount * 1e18) / perSecond; // Check if the backTimeInSeconds is 0 uint256 actualBackTimeInSeconds = backTimeInSeconds / 1e18; // Check if the actualBackTimeInSeconds is 0 if (actualBackTimeInSeconds == 0) revert CustomError("actualBackTimeInSeconds is 0"); // Calculate the adjusted start time after partial APY fees collection uint256 adjustedStartTime = timeStartedBorrow + actualBackTimeInSeconds; // Collect the APY fees partially collectTreasuryFeesPartially(_doughIndex, _token, address(this), scaledInterest, _partialAmount, adjustedStartTime); } /** * @notice Collects the APY fees for the given token * @param _doughIndex The DoughIndex address * @param _dsaAddress The DSA address * @param _token: The whitelisted token address * @param _scaledInterest The scaled interest of APY fees */ function collectTreasuryFees(address _doughIndex, address _dsaAddress, address _token, uint256 _scaledInterest) private { // Borrow the APY fees from the Aave V3 pool _I_AAVE_V3_POOL.borrow(_token, _scaledInterest, VARIABLE_RATE_MODE, 0, address(this)); // Transfer the fee to the treasury IERC20(_token).safeTransfer(IDoughIndex(_doughIndex).treasury(), _scaledInterest); // Update the borrow start date to now, as a new fee period starts IDoughIndex(_doughIndex).updateBorrowDate(CONNECTOR_ID0, block.timestamp, _dsaAddress, _token); } /** * @notice Collects the APY fees for the given token partially * @param _token: The token address to collect the APY fees * @param _dsaAddress: The DSA address to collect the APY fees * @param _scaledInterest: The scaled interest to collect the APY fees * @param _partialAmount: The partial amount to collect the APY fees * @param _adjustedStartTime: The adjusted start time after partial APY fees collection */ function collectTreasuryFeesPartially(address _doughIndex, address _token, address _dsaAddress, uint256 _scaledInterest, uint256 _partialAmount, uint256 _adjustedStartTime) private { // Check if the scaled interest is greater than the partial amount if (_scaledInterest >= _partialAmount) { // Borrow the APY fees from the Aave V3 pool _I_AAVE_V3_POOL.borrow(_token, _partialAmount, VARIABLE_RATE_MODE, 0, address(this)); // Transfer the fee to the treasury IERC20(_token).safeTransfer(IDoughIndex(_doughIndex).treasury(), _partialAmount); // Update the borrow start date to now, as a new fee period starts IDoughIndex(_doughIndex).updateBorrowDate(CONNECTOR_ID0, _adjustedStartTime, _dsaAddress, _token); } } }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[{"internalType":"string","name":"errorMsg","type":"string"}],"name":"CustomError","type":"error"},{"inputs":[],"name":"ERC1167FailedCreateClone","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"AllowOnlyEOA","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"apyFee","type":"uint256"}],"name":"ApyFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"connectorId","type":"uint256"},{"indexed":false,"internalType":"address","name":"connectorAddress","type":"address"}],"name":"ConnectorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"DeletedTokenWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newDsaAddress","type":"address"},{"indexed":true,"internalType":"address","name":"ownerAddress","type":"address"}],"name":"DsaCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"aaveActionsConnector","type":"address"}],"name":"NewAaveActionsConnector","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"borrowFormula","type":"address"}],"name":"NewBorrowFormula","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"deleverageAsset","type":"address"}],"name":"NewDeleverageAsset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"deleverageAutomation","type":"address"}],"name":"NewDeleverageAutomation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minDeleveragingRatio","type":"uint256"}],"name":"NewDeleveragingRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newDoughIndex","type":"address"}],"name":"NewDoughIndex","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newMultisig","type":"address"}],"name":"NewDoughMultisig","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"dsaMasterClone","type":"address"}],"name":"NewDsaMasterClone","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"flashBorrower","type":"address"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"NewFlashBorrower","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"feeRatio","type":"uint256"}],"name":"NewMinHealthFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"shieldAutomation","type":"address"}],"name":"NewShieldAutomation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint8","name":"decimals","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"minInterest","type":"uint256"}],"name":"NewTokenWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"treasuryAddress","type":"address"}],"name":"NewTreasuryAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vaultAutomation","type":"address"}],"name":"NewVaultAutomation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"address","name":"dsaAddress","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"connector","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timeNow","type":"uint256"}],"name":"UpdateBorrowDate","type":"event"},{"inputs":[],"name":"aaveActionsAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowOnlyEOA","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"apyFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_dsaAddress","type":"address"}],"name":"borrowFormula","outputs":[{"internalType":"uint256","name":"_debtAmount","type":"uint256"},{"internalType":"uint256","name":"_totalAmount","type":"uint256"},{"internalType":"uint256","name":"_scaledInterest","type":"uint256"},{"internalType":"uint256","name":"_minInterest","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"borrowFormulaAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_dsaAddress","type":"address"}],"name":"borrowFormulaInterest","outputs":[{"internalType":"uint256","name":"_scaledInterest","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buildDoughDsa","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"deleteWhitelistedTokenAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deleverageAsset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deleverageAutomation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dsaCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dsaMasterCopy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getDoughConnector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_dsaAddress","type":"address"}],"name":"getDoughDsa","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_dsaAddress","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"getDsaBorrowStartDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getDsaByID","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"getFlashBorrowers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"getOwnerOfDoughDsa","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getTokenDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getTokenIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getTokenMinInterest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWhitelistedTokenList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_multisig","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_deleveratingAsset","type":"address"},{"internalType":"address","name":"_deleverageAutomation","type":"address"},{"internalType":"uint256","name":"_apyFee","type":"uint256"},{"internalType":"uint256","name":"_minDeleveragingRatio","type":"uint256"},{"internalType":"uint256","name":"_minHealthFactorRatio","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minDeleveragingRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minHealthFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"multisig","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"setAllowOnlyEOA","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_apyFee","type":"uint256"}],"name":"setApyFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_connectorId","type":"uint256"},{"internalType":"address","name":"_connectorsAddr","type":"address"}],"name":"setConnectors","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_deleverageAutomation","type":"address"}],"name":"setDeleverageAutomation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_dsaMasterCopy","type":"address"}],"name":"setDsaMasterClone","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_flashBorrower","type":"address"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"setFlashBorrower","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minHealthFactor","type":"uint256"}],"name":"setMinAllowedHealthFactorRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minDeleveragingRatio","type":"uint256"}],"name":"setMinDeleveragingRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_flashBorrowers","type":"address[]"},{"internalType":"bool[]","name":"_status","type":"bool[]"}],"name":"setMultipleFlashBorrowers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAaveActions","type":"address"}],"name":"setNewAaveActions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newBorrowFormula","type":"address"}],"name":"setNewBorrowFormula","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newMultiSig","type":"address"}],"name":"setNewMultisig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_shieldAutomation","type":"address"}],"name":"setNewShieldAutomation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vaultAutomation","type":"address"}],"name":"setNewVaultAutomation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"uint256","name":"_minInterest","type":"uint256"}],"name":"setNewWhitelistedToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shieldAutomation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_connectorID","type":"uint256"},{"internalType":"uint256","name":"_time","type":"uint256"},{"internalType":"address","name":"_dsaAddress","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"updateBorrowDate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_deleverageAsset","type":"address"}],"name":"updateDeleverageAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultAutomation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"whitelistedTokenList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedTokens","outputs":[{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"minInterest","type":"uint256"},{"internalType":"uint256","name":"tokenIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506123fc806100206000396000f3fe608060405234801561001057600080fd5b50600436106102d65760003560e01c80638a29831f11610182578063cb937593116100e9578063e77fc7a4116100a2578063f2e6a9d31161007c578063f2e6a9d314610772578063f8d9ae1b14610785578063fa69fc21146107be578063fd436016146107d157600080fd5b8063e77fc7a414610723578063eb423d8d14610736578063f0f442601461075f57600080fd5b8063cb9375931461067c578063cceaa4071461068f578063daf9c210146106a2578063de2fb6b3146106f4578063e1b4264c14610707578063e4c521251461071057600080fd5b8063aebb25401161013b578063aebb254014610614578063afacacdc14610627578063bddff7491461063a578063c079d7bb1461064d578063c19980be14610656578063c6f5ee8d1461066957600080fd5b80638a29831f1461058f5780639306574c146105b257806394ca7aed146105ba57806395232285146105c35780639e12a4db146105d6578063aaa8a8b8146105ff57600080fd5b80634ee785d81161024157806366c0bd24116101fa5780637a6cefac116101d45780637a6cefac146105435780637b81cc14146105565780637f254ca514610569578063845869b51461057c57600080fd5b806366c0bd24146104c65780636f8e1c39146104f2578063785c7cf61461050557600080fd5b80634ee785d8146104345780635097daed146104475780635ca266f31461047a5780635f5b357d1461048d57806361d027b3146104a057806365b44790146104b357600080fd5b80632cd7a784116102935780632cd7a7841461039f5780632dd0744d146103cb57806337b7cbb2146103e85780634255b1d9146103fb57806346883f421461040e5780634783c35b1461042157600080fd5b806301e33667146102db5780630a3892ec146102f05780631380720414610320578063157374ed1461033757806319f46ae51461034a5780632b2e4ecd14610376575b600080fd5b6102ee6102e9366004611f31565b6107e4565b005b600a54610303906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61032960015481565b604051908152602001610317565b6102ee610345366004611f6d565b61095f565b610329610358366004611f86565b6001600160a01b031660009081526010602052604090206001015490565b610303610384366004611f6d565b6013602052600090815260409020546001600160a01b031681565b6103036103ad366004611f86565b6001600160a01b039081166000908152601160205260409020541690565b6000546103d89060ff1681565b6040519015158152602001610317565b6102ee6103f6366004611f86565b6109c6565b6102ee610409366004611fa1565b610ad1565b61032961041c366004611fcd565b610b62565b600754610303906001600160a01b031681565b6102ee610442366004611ff7565b610be2565b61045a610455366004611fcd565b610d34565b604080519485526020850193909352918301526060820152608001610317565b6102ee610488366004611f6d565b610dce565b600954610303906001600160a01b031681565b600854610303906001600160a01b031681565b6102ee6104c1366004612089565b610e2e565b6103296104d4366004611f86565b6001600160a01b031660009081526010602052604090206002015490565b6102ee610500366004611f6d565b610ebd565b610531610513366004611f86565b6001600160a01b031660009081526010602052604090205460ff1690565b60405160ff9091168152602001610317565b600c54610303906001600160a01b031681565b6102ee610564366004612103565b610f1d565b6102ee61057736600461213a565b61103d565b600654610303906001600160a01b031681565b6103d861059d366004611f86565b60156020526000908152604090205460ff1681565b6103036111be565b61032960045481565b6102ee6105d136600461217f565b61139c565b6103036105e4366004611f6d565b6014602052600090815260409020546001600160a01b031681565b610607611408565b604051610317919061219c565b6102ee610622366004611f86565b61146a565b600e54610303906001600160a01b031681565b610303610648366004611f6d565b61150a565b61032960025481565b6102ee610664366004611f86565b611534565b6102ee610677366004611f86565b61178c565b6102ee61068a366004611f86565b611805565b6102ee61069d366004611f86565b61187e565b6106d56106b0366004611f86565b60106020526000908152604090208054600182015460029092015460ff909116919083565b6040805160ff9094168452602084019290925290820152606001610317565b600b54610303906001600160a01b031681565b61032960035481565b6102ee61071e366004611f86565b6118f7565b6102ee6107313660046121e9565b611997565b610303610744366004611f86565b6012602052600090815260409020546001600160a01b031681565b6102ee61076d366004611f86565b611b0a565b6102ee610780366004611f86565b611baa565b610329610793366004611fcd565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205490565b6102ee6107cc366004611f86565b611c4a565b600d54610303906001600160a01b031681565b6007546001600160a01b03163314610818576040516346b7545f60e11b815260040161080f90612258565b60405180910390fd5b80600003610869576040516346b7545f60e11b815260206004820152601960248201527f6d7573742062652067726561746572207468616e207a65726f00000000000000604482015260640161080f565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038416016108ca576040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156108c4573d6000803e3d6000fd5b50505050565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015610911573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610935919061228f565b905081818111156109435750805b6109576001600160a01b0386168583611cea565b50505b505050565b6007546001600160a01b0316331461098a576040516346b7545f60e11b815260040161080f90612258565b60018190556040518181527f54f22940b5e8318291f7eda0c04584e9b008109c407d4c14b92f866a1b9e73d5906020015b60405180910390a150565b6007546001600160a01b031633146109f1576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038116610a18576040516346b7545f60e11b815260040161080f906122a8565b6001600160a01b03811660009081526010602052604081205460ff169003610a83576040516346b7545f60e11b815260206004820152601860248201527f746f6b656e206973206e6f742077686974656c69737465640000000000000000604482015260640161080f565b600980546001600160a01b0319166001600160a01b0383169081179091556040519081527fa58c797baddb244610d8a7afffb25577d3c43d3e2f18447225a01e14ef017a7e906020016109bb565b6007546001600160a01b03163314610afc576040516346b7545f60e11b815260040161080f90612258565b60008281526014602090815260409182902080546001600160a01b0319166001600160a01b0385169081179091558251858152918201527f39afbac6c8805382cbcdde27b81f6b1a318f77bec1337854f676f0a0c1737600910160405180910390a15050565b600a546040516323441fa160e11b81526001600160a01b038481166004830152838116602483015260009216906346883f4290604401602060405180830381865afa158015610bb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd9919061228f565b90505b92915050565b6000848152601460205260409020546001600160a01b039081169083163314801590610c175750336001600160a01b03821614155b15610c56576040516346b7545f60e11b815260206004820152600e60248201526d24b73b30b634b21021b0b63632b960911b604482015260640161080f565b6001600160a01b0383811660009081526012602052604090205416610cb4576040516346b7545f60e11b8152602060048201526013602482015272125b99195e081114d0481b9bdd08199bdd5b99606a1b604482015260640161080f565b6001600160a01b038381166000818152600f602090815260408083209487168084529482529182902088905581513381529081019290925281019190915260608101869052608081018590527fff30a7cae7c37057cd0e9a1c0b1cf8d4029a272404fb2417bf1ba0de392322d59060a00160405180910390a15050505050565b600a54604051635097daed60e01b81526001600160a01b03848116600483015283811660248301526000928392839283928392839283928392911690635097daed90604401608060405180830381865afa158015610d96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dba91906122d6565b929d919c509a509098509650505050505050565b6007546001600160a01b03163314610df9576040516346b7545f60e11b815260040161080f90612258565b60048190556040518181527f3bcc98b4f2c08fb2fd3903f8b7af93eecfb378b394cb0cee251a486af1e7ef86906020016109bb565b6007546001600160a01b03163314610e59576040516346b7545f60e11b815260040161080f90612258565b60005b8381101561095757610eb5858583818110610e7957610e7961230c565b9050602002016020810190610e8e9190611f86565b848484818110610ea057610ea061230c565b9050602002016020810190610564919061217f565b600101610e5c565b6007546001600160a01b03163314610ee8576040516346b7545f60e11b815260040161080f90612258565b60038190556040518181527f559840e4a63a2b223f449d8c3e2c56e023e37a4f16a93c134a726e3ef47ada32906020016109bb565b6007546001600160a01b03163314610f48576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038281166000908152601560209081526040808320805460ff191686151590811790915560119092529091205460055492169190600103610ff35760005b81811015610ff1576001600160a01b0383166000908152600f602052604081206005805483919085908110610fc457610fc461230c565b60009182526020808320909101546001600160a01b03168352820192909252604001902055600101610f8d565b505b604080516001600160a01b038616815284151560208201527f101db72e062229489fbb1daba8123b65a310d8851c7f7d2c32dee206145a070491015b60405180910390a150505050565b6007546001600160a01b03163314611068576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b03831661108f576040516346b7545f60e11b815260040161080f906122a8565b8160ff166000036110dc576040516346b7545f60e11b8152602060048201526016602482015275496e76616c696420746f6b656e20646563696d616c7360501b604482015260640161080f565b604080516060808201835260ff8581168084526020808501878152600580548789019081526001600160a01b038c166000818152601086528a812099518a5460ff1916981697909717895592516001808a01919091559051600290980197909755805496870181559093527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db090940180546001600160a01b031916831790558451918252928101929092529181018390527fceb26998c7462ab2ef1ff2d19aa0e99b990411052d57378658b81a1743b9f10e91015b60405180910390a1505050565b336000908152601160205260408120546001600160a01b03161561121b576040516346b7545f60e11b81526020600482015260136024820152721114d048185b1c9958591e4818dc99585d1959606a1b604482015260640161080f565b60005460ff1680156112335750333b63ffffffff1615155b1561127a576040516346b7545f60e11b81526020600482015260166024820152751114d0481b9bdd0818dbdb9d1c9858dd0b5bdddb995960521b604482015260640161080f565b600654600090611292906001600160a01b0316611d3c565b60405163485cc95560e01b81523360048201523060248201529091506001600160a01b0382169063485cc95590604401600060405180830381600087803b1580156112dc57600080fd5b505af11580156112f0573d6000803e3d6000fd5b505033600081815260116020908152604080832080546001600160a01b0389166001600160a01b03199182168117909255818552601284528285208054821690961790955560028054855260139093529083208054909416179092558154935090915061135c83612338565b909155505060405133906001600160a01b038316907ff5a1bc79de9aff9ae3c672fb1cf9efcae580127e9530c2a26cdace11b0d1d58c90600090a3919050565b6007546001600160a01b031633146113c7576040516346b7545f60e11b815260040161080f90612258565b6000805460ff19168215159081179091556040519081527f1f38e566275b2ecb0c8f594e102c7cca71d490f1fa065b73bb0946b96bc41c60906020016109bb565b6060600580548060200260200160405190810160405280929190818152602001828054801561146057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611442575b5050505050905090565b6007546001600160a01b03163314611495576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b0381166114bc576040516346b7545f60e11b815260040161080f906122a8565b600780546001600160a01b0319166001600160a01b0383169081179091556040519081527fca1b0e26998d621c76ed184e3913d796a255927db88191adee6b00250bbfd7c6906020016109bb565b6005818154811061151a57600080fd5b6000918252602090912001546001600160a01b0316905081565b6007546001600160a01b0316331461155f576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038116611586576040516346b7545f60e11b815260040161080f906122a8565b60055460009061159890600190612351565b90506000600582815481106115af576115af61230c565b6000918252602090912001546001600160a01b039081169150831681036116605760058054806115e1576115e1612364565b60008281526020808220600019908401810180546001600160a01b03191690559092019092556001600160a01b038516808352601082526040808420805460ff19168155600181018590556002019390935591519182527f6aca46e1f654964b57eba87988180e22b5eac089eede2de21ebb9185ab93517691016111b1565b6001600160a01b038082166000908152601060205260408082206002908101869055928616825290200154600580548490811061169f5761169f61230c565b600091825260209091200154600580546001600160a01b0390921691839081106116cb576116cb61230c565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600580548061170a5761170a612364565b60008281526020808220600019908401810180546001600160a01b03191690559092019092556001600160a01b038616808352601082526040808420805460ff19168155600181018590556002019390935591519182527f6aca46e1f654964b57eba87988180e22b5eac089eede2de21ebb9185ab935176910161102f565b50565b6007546001600160a01b031633146117b7576040516346b7545f60e11b815260040161080f90612258565b600d80546001600160a01b0319166001600160a01b0383169081179091556040519081527f644641a65d818bb837107d83002c03c77084a193208c1b2c5ea4a496c6b34bfa906020016109bb565b6007546001600160a01b03163314611830576040516346b7545f60e11b815260040161080f90612258565b600c80546001600160a01b0319166001600160a01b0383169081179091556040519081527fc266d0b46adf2f8d65456d02bdde8e7dd2160c69b7a7ad23c6512ba7d3590f21906020016109bb565b6007546001600160a01b031633146118a9576040516346b7545f60e11b815260040161080f90612258565b600e80546001600160a01b0319166001600160a01b0383169081179091556040519081527f97d67d674c873f1958217ed2f4709188da30c10e1a4e7371b32502ef79987240906020016109bb565b6007546001600160a01b03163314611922576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038116611949576040516346b7545f60e11b815260040161080f906122a8565b600680546001600160a01b0319166001600160a01b0383169081179091556040519081527fe544cb074b7f16a689a7f9df980fed3c9e78b29d56f7aa0ac6b0aa9efb402716906020016109bb565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff166000811580156119dd5750825b905060008267ffffffffffffffff1660011480156119fa5750303b155b905081158015611a08575080155b15611a265760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315611a5057845460ff60401b1916600160401b1785555b600c80546001600160a01b03808c166001600160a01b03199283161790925560048990556003889055600980548d8416908316179055600780548f841690831617905560088054928e169290911691909117905560018881556000805460ff191690911790558315611afc57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050505050565b6007546001600160a01b03163314611b35576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038116611b5c576040516346b7545f60e11b815260040161080f906122a8565b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527f8b4531436af204a864adc47c345e10cb5c4df79165aa0cb85fc45ac5b551517b906020016109bb565b6007546001600160a01b03163314611bd5576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038116611bfc576040516346b7545f60e11b815260040161080f906122a8565b600a80546001600160a01b0319166001600160a01b0383169081179091556040519081527f2ba08a61cc82c9bbe9de40ae484a4d5cb4328ad3fe0a1d9d3ba705a749b79cc4906020016109bb565b6007546001600160a01b03163314611c75576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038116611c9c576040516346b7545f60e11b815260040161080f906122a8565b600b80546001600160a01b0319166001600160a01b0383169081179091556040519081527f6a07c4aef018c4244cf3e4a217619446667db8e64eeda42ba6581d4784fb1107906020016109bb565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261095a908490611dae565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c176000526e5af43d82803e903d91602b57fd5bf38260781b17602052603760096000f090506001600160a01b038116611da9576040516330be1a3d60e21b815260040160405180910390fd5b919050565b6000611dc36001600160a01b03841683611e11565b90508051600014158015611de8575080806020019051810190611de6919061237a565b155b1561095a57604051635274afe760e01b81526001600160a01b038416600482015260240161080f565b6060610bd98383600084600080856001600160a01b03168486604051611e379190612397565b60006040518083038185875af1925050503d8060008114611e74576040519150601f19603f3d011682016040523d82523d6000602084013e611e79565b606091505b5091509150611e89868383611e95565b925050505b9392505050565b606082611eaa57611ea582611ef1565b611e8e565b8151158015611ec157506001600160a01b0384163b155b15611eea57604051639996b31560e01b81526001600160a01b038516600482015260240161080f565b5080611e8e565b805115611f015780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b80356001600160a01b0381168114611da957600080fd5b600080600060608486031215611f4657600080fd5b611f4f84611f1a565b9250611f5d60208501611f1a565b9150604084013590509250925092565b600060208284031215611f7f57600080fd5b5035919050565b600060208284031215611f9857600080fd5b610bd982611f1a565b60008060408385031215611fb457600080fd5b82359150611fc460208401611f1a565b90509250929050565b60008060408385031215611fe057600080fd5b611fe983611f1a565b9150611fc460208401611f1a565b6000806000806080858703121561200d57600080fd5b843593506020850135925061202460408601611f1a565b915061203260608601611f1a565b905092959194509250565b60008083601f84011261204f57600080fd5b50813567ffffffffffffffff81111561206757600080fd5b6020830191508360208260051b850101111561208257600080fd5b9250929050565b6000806000806040858703121561209f57600080fd5b843567ffffffffffffffff808211156120b757600080fd5b6120c38883890161203d565b909650945060208701359150808211156120dc57600080fd5b506120e98782880161203d565b95989497509550505050565b801515811461178957600080fd5b6000806040838503121561211657600080fd5b61211f83611f1a565b9150602083013561212f816120f5565b809150509250929050565b60008060006060848603121561214f57600080fd5b61215884611f1a565b9250602084013560ff8116811461216e57600080fd5b929592945050506040919091013590565b60006020828403121561219157600080fd5b8135611e8e816120f5565b6020808252825182820181905260009190848201906040850190845b818110156121dd5783516001600160a01b0316835292840192918401916001016121b8565b50909695505050505050565b600080600080600080600060e0888a03121561220457600080fd5b61220d88611f1a565b965061221b60208901611f1a565b955061222960408901611f1a565b945061223760608901611f1a565b9699959850939660808101359560a0820135955060c0909101359350915050565b60208082526018908201527f496e76616c6964206d756c746973696720616464726573730000000000000000604082015260600190565b6000602082840312156122a157600080fd5b5051919050565b602080825260149082015273496e76616c6964207a65726f206164647265737360601b604082015260600190565b600080600080608085870312156122ec57600080fd5b505082516020840151604085015160609095015191969095509092509050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161234a5761234a612322565b5060010190565b81810381811115610bdc57610bdc612322565b634e487b7160e01b600052603160045260246000fd5b60006020828403121561238c57600080fd5b8151611e8e816120f5565b6000825160005b818110156123b8576020818601810151858301520161239e565b50600092019182525091905056fea2646970667358221220e91243ddc3c3f50b0f5e8b241524d2b934731ac4f9b489993e25b81b3c94900264736f6c63430008180033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102d65760003560e01c80638a29831f11610182578063cb937593116100e9578063e77fc7a4116100a2578063f2e6a9d31161007c578063f2e6a9d314610772578063f8d9ae1b14610785578063fa69fc21146107be578063fd436016146107d157600080fd5b8063e77fc7a414610723578063eb423d8d14610736578063f0f442601461075f57600080fd5b8063cb9375931461067c578063cceaa4071461068f578063daf9c210146106a2578063de2fb6b3146106f4578063e1b4264c14610707578063e4c521251461071057600080fd5b8063aebb25401161013b578063aebb254014610614578063afacacdc14610627578063bddff7491461063a578063c079d7bb1461064d578063c19980be14610656578063c6f5ee8d1461066957600080fd5b80638a29831f1461058f5780639306574c146105b257806394ca7aed146105ba57806395232285146105c35780639e12a4db146105d6578063aaa8a8b8146105ff57600080fd5b80634ee785d81161024157806366c0bd24116101fa5780637a6cefac116101d45780637a6cefac146105435780637b81cc14146105565780637f254ca514610569578063845869b51461057c57600080fd5b806366c0bd24146104c65780636f8e1c39146104f2578063785c7cf61461050557600080fd5b80634ee785d8146104345780635097daed146104475780635ca266f31461047a5780635f5b357d1461048d57806361d027b3146104a057806365b44790146104b357600080fd5b80632cd7a784116102935780632cd7a7841461039f5780632dd0744d146103cb57806337b7cbb2146103e85780634255b1d9146103fb57806346883f421461040e5780634783c35b1461042157600080fd5b806301e33667146102db5780630a3892ec146102f05780631380720414610320578063157374ed1461033757806319f46ae51461034a5780632b2e4ecd14610376575b600080fd5b6102ee6102e9366004611f31565b6107e4565b005b600a54610303906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61032960015481565b604051908152602001610317565b6102ee610345366004611f6d565b61095f565b610329610358366004611f86565b6001600160a01b031660009081526010602052604090206001015490565b610303610384366004611f6d565b6013602052600090815260409020546001600160a01b031681565b6103036103ad366004611f86565b6001600160a01b039081166000908152601160205260409020541690565b6000546103d89060ff1681565b6040519015158152602001610317565b6102ee6103f6366004611f86565b6109c6565b6102ee610409366004611fa1565b610ad1565b61032961041c366004611fcd565b610b62565b600754610303906001600160a01b031681565b6102ee610442366004611ff7565b610be2565b61045a610455366004611fcd565b610d34565b604080519485526020850193909352918301526060820152608001610317565b6102ee610488366004611f6d565b610dce565b600954610303906001600160a01b031681565b600854610303906001600160a01b031681565b6102ee6104c1366004612089565b610e2e565b6103296104d4366004611f86565b6001600160a01b031660009081526010602052604090206002015490565b6102ee610500366004611f6d565b610ebd565b610531610513366004611f86565b6001600160a01b031660009081526010602052604090205460ff1690565b60405160ff9091168152602001610317565b600c54610303906001600160a01b031681565b6102ee610564366004612103565b610f1d565b6102ee61057736600461213a565b61103d565b600654610303906001600160a01b031681565b6103d861059d366004611f86565b60156020526000908152604090205460ff1681565b6103036111be565b61032960045481565b6102ee6105d136600461217f565b61139c565b6103036105e4366004611f6d565b6014602052600090815260409020546001600160a01b031681565b610607611408565b604051610317919061219c565b6102ee610622366004611f86565b61146a565b600e54610303906001600160a01b031681565b610303610648366004611f6d565b61150a565b61032960025481565b6102ee610664366004611f86565b611534565b6102ee610677366004611f86565b61178c565b6102ee61068a366004611f86565b611805565b6102ee61069d366004611f86565b61187e565b6106d56106b0366004611f86565b60106020526000908152604090208054600182015460029092015460ff909116919083565b6040805160ff9094168452602084019290925290820152606001610317565b600b54610303906001600160a01b031681565b61032960035481565b6102ee61071e366004611f86565b6118f7565b6102ee6107313660046121e9565b611997565b610303610744366004611f86565b6012602052600090815260409020546001600160a01b031681565b6102ee61076d366004611f86565b611b0a565b6102ee610780366004611f86565b611baa565b610329610793366004611fcd565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205490565b6102ee6107cc366004611f86565b611c4a565b600d54610303906001600160a01b031681565b6007546001600160a01b03163314610818576040516346b7545f60e11b815260040161080f90612258565b60405180910390fd5b80600003610869576040516346b7545f60e11b815260206004820152601960248201527f6d7573742062652067726561746572207468616e207a65726f00000000000000604482015260640161080f565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038416016108ca576040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156108c4573d6000803e3d6000fd5b50505050565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015610911573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610935919061228f565b905081818111156109435750805b6109576001600160a01b0386168583611cea565b50505b505050565b6007546001600160a01b0316331461098a576040516346b7545f60e11b815260040161080f90612258565b60018190556040518181527f54f22940b5e8318291f7eda0c04584e9b008109c407d4c14b92f866a1b9e73d5906020015b60405180910390a150565b6007546001600160a01b031633146109f1576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038116610a18576040516346b7545f60e11b815260040161080f906122a8565b6001600160a01b03811660009081526010602052604081205460ff169003610a83576040516346b7545f60e11b815260206004820152601860248201527f746f6b656e206973206e6f742077686974656c69737465640000000000000000604482015260640161080f565b600980546001600160a01b0319166001600160a01b0383169081179091556040519081527fa58c797baddb244610d8a7afffb25577d3c43d3e2f18447225a01e14ef017a7e906020016109bb565b6007546001600160a01b03163314610afc576040516346b7545f60e11b815260040161080f90612258565b60008281526014602090815260409182902080546001600160a01b0319166001600160a01b0385169081179091558251858152918201527f39afbac6c8805382cbcdde27b81f6b1a318f77bec1337854f676f0a0c1737600910160405180910390a15050565b600a546040516323441fa160e11b81526001600160a01b038481166004830152838116602483015260009216906346883f4290604401602060405180830381865afa158015610bb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd9919061228f565b90505b92915050565b6000848152601460205260409020546001600160a01b039081169083163314801590610c175750336001600160a01b03821614155b15610c56576040516346b7545f60e11b815260206004820152600e60248201526d24b73b30b634b21021b0b63632b960911b604482015260640161080f565b6001600160a01b0383811660009081526012602052604090205416610cb4576040516346b7545f60e11b8152602060048201526013602482015272125b99195e081114d0481b9bdd08199bdd5b99606a1b604482015260640161080f565b6001600160a01b038381166000818152600f602090815260408083209487168084529482529182902088905581513381529081019290925281019190915260608101869052608081018590527fff30a7cae7c37057cd0e9a1c0b1cf8d4029a272404fb2417bf1ba0de392322d59060a00160405180910390a15050505050565b600a54604051635097daed60e01b81526001600160a01b03848116600483015283811660248301526000928392839283928392839283928392911690635097daed90604401608060405180830381865afa158015610d96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dba91906122d6565b929d919c509a509098509650505050505050565b6007546001600160a01b03163314610df9576040516346b7545f60e11b815260040161080f90612258565b60048190556040518181527f3bcc98b4f2c08fb2fd3903f8b7af93eecfb378b394cb0cee251a486af1e7ef86906020016109bb565b6007546001600160a01b03163314610e59576040516346b7545f60e11b815260040161080f90612258565b60005b8381101561095757610eb5858583818110610e7957610e7961230c565b9050602002016020810190610e8e9190611f86565b848484818110610ea057610ea061230c565b9050602002016020810190610564919061217f565b600101610e5c565b6007546001600160a01b03163314610ee8576040516346b7545f60e11b815260040161080f90612258565b60038190556040518181527f559840e4a63a2b223f449d8c3e2c56e023e37a4f16a93c134a726e3ef47ada32906020016109bb565b6007546001600160a01b03163314610f48576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038281166000908152601560209081526040808320805460ff191686151590811790915560119092529091205460055492169190600103610ff35760005b81811015610ff1576001600160a01b0383166000908152600f602052604081206005805483919085908110610fc457610fc461230c565b60009182526020808320909101546001600160a01b03168352820192909252604001902055600101610f8d565b505b604080516001600160a01b038616815284151560208201527f101db72e062229489fbb1daba8123b65a310d8851c7f7d2c32dee206145a070491015b60405180910390a150505050565b6007546001600160a01b03163314611068576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b03831661108f576040516346b7545f60e11b815260040161080f906122a8565b8160ff166000036110dc576040516346b7545f60e11b8152602060048201526016602482015275496e76616c696420746f6b656e20646563696d616c7360501b604482015260640161080f565b604080516060808201835260ff8581168084526020808501878152600580548789019081526001600160a01b038c166000818152601086528a812099518a5460ff1916981697909717895592516001808a01919091559051600290980197909755805496870181559093527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db090940180546001600160a01b031916831790558451918252928101929092529181018390527fceb26998c7462ab2ef1ff2d19aa0e99b990411052d57378658b81a1743b9f10e91015b60405180910390a1505050565b336000908152601160205260408120546001600160a01b03161561121b576040516346b7545f60e11b81526020600482015260136024820152721114d048185b1c9958591e4818dc99585d1959606a1b604482015260640161080f565b60005460ff1680156112335750333b63ffffffff1615155b1561127a576040516346b7545f60e11b81526020600482015260166024820152751114d0481b9bdd0818dbdb9d1c9858dd0b5bdddb995960521b604482015260640161080f565b600654600090611292906001600160a01b0316611d3c565b60405163485cc95560e01b81523360048201523060248201529091506001600160a01b0382169063485cc95590604401600060405180830381600087803b1580156112dc57600080fd5b505af11580156112f0573d6000803e3d6000fd5b505033600081815260116020908152604080832080546001600160a01b0389166001600160a01b03199182168117909255818552601284528285208054821690961790955560028054855260139093529083208054909416179092558154935090915061135c83612338565b909155505060405133906001600160a01b038316907ff5a1bc79de9aff9ae3c672fb1cf9efcae580127e9530c2a26cdace11b0d1d58c90600090a3919050565b6007546001600160a01b031633146113c7576040516346b7545f60e11b815260040161080f90612258565b6000805460ff19168215159081179091556040519081527f1f38e566275b2ecb0c8f594e102c7cca71d490f1fa065b73bb0946b96bc41c60906020016109bb565b6060600580548060200260200160405190810160405280929190818152602001828054801561146057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611442575b5050505050905090565b6007546001600160a01b03163314611495576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b0381166114bc576040516346b7545f60e11b815260040161080f906122a8565b600780546001600160a01b0319166001600160a01b0383169081179091556040519081527fca1b0e26998d621c76ed184e3913d796a255927db88191adee6b00250bbfd7c6906020016109bb565b6005818154811061151a57600080fd5b6000918252602090912001546001600160a01b0316905081565b6007546001600160a01b0316331461155f576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038116611586576040516346b7545f60e11b815260040161080f906122a8565b60055460009061159890600190612351565b90506000600582815481106115af576115af61230c565b6000918252602090912001546001600160a01b039081169150831681036116605760058054806115e1576115e1612364565b60008281526020808220600019908401810180546001600160a01b03191690559092019092556001600160a01b038516808352601082526040808420805460ff19168155600181018590556002019390935591519182527f6aca46e1f654964b57eba87988180e22b5eac089eede2de21ebb9185ab93517691016111b1565b6001600160a01b038082166000908152601060205260408082206002908101869055928616825290200154600580548490811061169f5761169f61230c565b600091825260209091200154600580546001600160a01b0390921691839081106116cb576116cb61230c565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600580548061170a5761170a612364565b60008281526020808220600019908401810180546001600160a01b03191690559092019092556001600160a01b038616808352601082526040808420805460ff19168155600181018590556002019390935591519182527f6aca46e1f654964b57eba87988180e22b5eac089eede2de21ebb9185ab935176910161102f565b50565b6007546001600160a01b031633146117b7576040516346b7545f60e11b815260040161080f90612258565b600d80546001600160a01b0319166001600160a01b0383169081179091556040519081527f644641a65d818bb837107d83002c03c77084a193208c1b2c5ea4a496c6b34bfa906020016109bb565b6007546001600160a01b03163314611830576040516346b7545f60e11b815260040161080f90612258565b600c80546001600160a01b0319166001600160a01b0383169081179091556040519081527fc266d0b46adf2f8d65456d02bdde8e7dd2160c69b7a7ad23c6512ba7d3590f21906020016109bb565b6007546001600160a01b031633146118a9576040516346b7545f60e11b815260040161080f90612258565b600e80546001600160a01b0319166001600160a01b0383169081179091556040519081527f97d67d674c873f1958217ed2f4709188da30c10e1a4e7371b32502ef79987240906020016109bb565b6007546001600160a01b03163314611922576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038116611949576040516346b7545f60e11b815260040161080f906122a8565b600680546001600160a01b0319166001600160a01b0383169081179091556040519081527fe544cb074b7f16a689a7f9df980fed3c9e78b29d56f7aa0ac6b0aa9efb402716906020016109bb565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff166000811580156119dd5750825b905060008267ffffffffffffffff1660011480156119fa5750303b155b905081158015611a08575080155b15611a265760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315611a5057845460ff60401b1916600160401b1785555b600c80546001600160a01b03808c166001600160a01b03199283161790925560048990556003889055600980548d8416908316179055600780548f841690831617905560088054928e169290911691909117905560018881556000805460ff191690911790558315611afc57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050505050565b6007546001600160a01b03163314611b35576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038116611b5c576040516346b7545f60e11b815260040161080f906122a8565b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527f8b4531436af204a864adc47c345e10cb5c4df79165aa0cb85fc45ac5b551517b906020016109bb565b6007546001600160a01b03163314611bd5576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038116611bfc576040516346b7545f60e11b815260040161080f906122a8565b600a80546001600160a01b0319166001600160a01b0383169081179091556040519081527f2ba08a61cc82c9bbe9de40ae484a4d5cb4328ad3fe0a1d9d3ba705a749b79cc4906020016109bb565b6007546001600160a01b03163314611c75576040516346b7545f60e11b815260040161080f90612258565b6001600160a01b038116611c9c576040516346b7545f60e11b815260040161080f906122a8565b600b80546001600160a01b0319166001600160a01b0383169081179091556040519081527f6a07c4aef018c4244cf3e4a217619446667db8e64eeda42ba6581d4784fb1107906020016109bb565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261095a908490611dae565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c176000526e5af43d82803e903d91602b57fd5bf38260781b17602052603760096000f090506001600160a01b038116611da9576040516330be1a3d60e21b815260040160405180910390fd5b919050565b6000611dc36001600160a01b03841683611e11565b90508051600014158015611de8575080806020019051810190611de6919061237a565b155b1561095a57604051635274afe760e01b81526001600160a01b038416600482015260240161080f565b6060610bd98383600084600080856001600160a01b03168486604051611e379190612397565b60006040518083038185875af1925050503d8060008114611e74576040519150601f19603f3d011682016040523d82523d6000602084013e611e79565b606091505b5091509150611e89868383611e95565b925050505b9392505050565b606082611eaa57611ea582611ef1565b611e8e565b8151158015611ec157506001600160a01b0384163b155b15611eea57604051639996b31560e01b81526001600160a01b038516600482015260240161080f565b5080611e8e565b805115611f015780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b80356001600160a01b0381168114611da957600080fd5b600080600060608486031215611f4657600080fd5b611f4f84611f1a565b9250611f5d60208501611f1a565b9150604084013590509250925092565b600060208284031215611f7f57600080fd5b5035919050565b600060208284031215611f9857600080fd5b610bd982611f1a565b60008060408385031215611fb457600080fd5b82359150611fc460208401611f1a565b90509250929050565b60008060408385031215611fe057600080fd5b611fe983611f1a565b9150611fc460208401611f1a565b6000806000806080858703121561200d57600080fd5b843593506020850135925061202460408601611f1a565b915061203260608601611f1a565b905092959194509250565b60008083601f84011261204f57600080fd5b50813567ffffffffffffffff81111561206757600080fd5b6020830191508360208260051b850101111561208257600080fd5b9250929050565b6000806000806040858703121561209f57600080fd5b843567ffffffffffffffff808211156120b757600080fd5b6120c38883890161203d565b909650945060208701359150808211156120dc57600080fd5b506120e98782880161203d565b95989497509550505050565b801515811461178957600080fd5b6000806040838503121561211657600080fd5b61211f83611f1a565b9150602083013561212f816120f5565b809150509250929050565b60008060006060848603121561214f57600080fd5b61215884611f1a565b9250602084013560ff8116811461216e57600080fd5b929592945050506040919091013590565b60006020828403121561219157600080fd5b8135611e8e816120f5565b6020808252825182820181905260009190848201906040850190845b818110156121dd5783516001600160a01b0316835292840192918401916001016121b8565b50909695505050505050565b600080600080600080600060e0888a03121561220457600080fd5b61220d88611f1a565b965061221b60208901611f1a565b955061222960408901611f1a565b945061223760608901611f1a565b9699959850939660808101359560a0820135955060c0909101359350915050565b60208082526018908201527f496e76616c6964206d756c746973696720616464726573730000000000000000604082015260600190565b6000602082840312156122a157600080fd5b5051919050565b602080825260149082015273496e76616c6964207a65726f206164647265737360601b604082015260600190565b600080600080608085870312156122ec57600080fd5b505082516020840151604085015160609095015191969095509092509050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161234a5761234a612322565b5060010190565b81810381811115610bdc57610bdc612322565b634e487b7160e01b600052603160045260246000fd5b60006020828403121561238c57600080fd5b8151611e8e816120f5565b6000825160005b818110156123b8576020818601810151858301520161239e565b50600092019182525091905056fea2646970667358221220e91243ddc3c3f50b0f5e8b241524d2b934731ac4f9b489993e25b81b3c94900264736f6c63430008180033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.