Contract Overview
Balance:
0 FTM
FTM Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0xd97fddd6d24965efb46e64a03ee0161ab94a4c8e405cd3d8c9a6694a2b87a6ef | Initialize | 41559267 | 264 days 21 hrs ago | 0x3bff7fd5aacb1a22e1dd3ddbd8cfb8622a9e9a5b | IN | 0x5110ec1e9f9ee08ea8b884eb3be4faace8960fd8 | 0 FTM | 0.239390174643 | |
0xafc28574e44417d41bb7e3c27594e1b678202125d8550ee3577c39c1a430e427 | 0x60806040 | 35448399 | 347 days 7 hrs ago | 0xb98d4d4e205aff4d4755e9df19bd0b8bd4e0f148 | IN | Create: FujiVaultFTM | 0 FTM | 0.862116130114 |
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
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 Name:
FujiVaultFTM
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 500 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol"; import "../abstracts/vault/VaultBaseUpgradeable.sol"; import "../interfaces/IVault.sol"; import "../interfaces/IHarvester.sol"; import "../interfaces/ISwapper.sol"; import "../interfaces/IERC20Extended.sol"; import "../interfaces/chainlink/AggregatorV3Interface.sol"; import "../interfaces/IFujiAdmin.sol"; import "../interfaces/IFujiOracle.sol"; import "../interfaces/IFujiERC1155.sol"; import "../interfaces/IProvider.sol"; import "../libraries/Errors.sol"; import "./libraries/LibUniversalERC20UpgradeableFTM.sol"; import "./nft-bonds/interfaces/INFTGame.sol"; /** * @dev Contract for the interaction of Fuji users with the Fuji protocol. * - Performs deposit, withdraw, borrow and payback functions. * - Contains the fallback logic to perform a switch of providers. */ contract FujiVaultFTM is VaultBaseUpgradeable, ReentrancyGuardUpgradeable, IVault { using SafeERC20Upgradeable for IERC20Upgradeable; using LibUniversalERC20UpgradeableFTM for IERC20Upgradeable; /** * @dev Log a change in fuji admin address */ event NFTGameChanged(address newNFTGame); address public constant FTM = 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF; // Safety factor Factor public safetyF; // Collateralization factor Factor public collatF; // Protocol Fee factor Factor public override protocolFee; // Bonus factor for liquidation Factor public bonusLiqF; //State variables address[] public providers; address public override activeProvider; IFujiAdmin private _fujiAdmin; address public override fujiERC1155; IFujiOracle public oracle; string public name; uint8 internal _collateralAssetDecimals; uint8 internal _borrowAssetDecimals; uint256 public constant ONE_YEAR = 60 * 60 * 24 * 365; mapping(address => uint256) internal _userFeeTimestamps; // to be used for protocol fee calculation uint256 public remainingProtocolFee; address public nftGame; /** * @dev Throws if caller is not the 'owner' or the '_controller' address stored in {FujiAdmin} */ modifier isAuthorized() { require( msg.sender == owner() || msg.sender == _fujiAdmin.getController(), Errors.VL_NOT_AUTHORIZED ); _; } /** * @dev Throws if caller is not the '_flasher' address stored in {FujiAdmin} */ modifier onlyFlash() { require(msg.sender == _fujiAdmin.getFlasher(), Errors.VL_NOT_AUTHORIZED); _; } /** * @dev Throws if caller is not the '_fliquidator' address stored in {FujiAdmin} */ modifier onlyFliquidator() { require(msg.sender == _fujiAdmin.getFliquidator(), Errors.VL_NOT_AUTHORIZED); _; } /** * @dev Initializes the contract by setting: * - Type of collateral and borrow asset of this vault. * - Addresses for fujiAdmin, _oracle. */ function initialize( address _fujiadmin, address _oracle, address _collateralAsset, address _borrowAsset ) external initializer { require( _fujiadmin != address(0) && _oracle != address(0) && _collateralAsset != address(0) && _borrowAsset != address(0), Errors.VL_ZERO_ADDR ); __Ownable_init(); __Pausable_init(); __ReentrancyGuard_init(); _fujiAdmin = IFujiAdmin(_fujiadmin); oracle = IFujiOracle(_oracle); vAssets.collateralAsset = _collateralAsset; vAssets.borrowAsset = _borrowAsset; string memory collateralSymbol; string memory borrowSymbol; if (_collateralAsset == FTM) { collateralSymbol = "FTM"; _collateralAssetDecimals = 18; } else { collateralSymbol = IERC20Extended(_collateralAsset).symbol(); _collateralAssetDecimals = IERC20Extended(_collateralAsset).decimals(); } if (_borrowAsset == FTM) { borrowSymbol = "FTM"; _borrowAssetDecimals = 18; } else { borrowSymbol = IERC20Extended(_borrowAsset).symbol(); _borrowAssetDecimals = IERC20Extended(_borrowAsset).decimals(); } name = string(abi.encodePacked("Vault", collateralSymbol, borrowSymbol)); // 1.05 safetyF.a = 21; safetyF.b = 20; // 1.269 collatF.a = 80; collatF.b = 63; // 0.05 bonusLiqF.a = 1; bonusLiqF.b = 20; protocolFee.a = 1; protocolFee.b = 1000; } receive() external payable {} //Core functions /** * @dev Deposits collateral and borrows underlying in a single function call from activeProvider * @param _collateralAmount: amount to be deposited * @param _borrowAmount: amount to be borrowed */ function depositAndBorrow(uint256 _collateralAmount, uint256 _borrowAmount) external payable { updateF1155Balances(); _internalDeposit(_collateralAmount); _internalBorrow(_borrowAmount); } /** * @dev Paybacks the underlying asset and withdraws collateral in a single function call from activeProvider * @param _paybackAmount: amount of underlying asset to be payback, pass -1 to pay full amount * @param _collateralAmount: amount of collateral to be withdrawn, pass -1 to withdraw maximum amount */ function paybackAndWithdraw(int256 _paybackAmount, int256 _collateralAmount) external payable { updateF1155Balances(); _internalPayback(_paybackAmount); _internalWithdraw(_collateralAmount); } /** * @dev Deposit Vault's type collateral to activeProvider * call Controller checkrates * @param _collateralAmount: to be deposited * Emits a {Deposit} event. */ function deposit(uint256 _collateralAmount) public payable override { updateF1155Balances(); _internalDeposit(_collateralAmount); } /** * @dev Withdraws Vault's type collateral from activeProvider * call Controller checkrates - by normal users * @param _withdrawAmount: amount of collateral to withdraw * otherwise pass any 'negative number' to withdraw maximum amount possible of collateral (including safety factors) * Emits a {Withdraw} event. */ function withdraw(int256 _withdrawAmount) public override nonReentrant { updateF1155Balances(); _internalWithdraw(_withdrawAmount); } /** * @dev Withdraws Vault's type collateral from activeProvider * call Controller checkrates - by Fliquidator * @param _withdrawAmount: amount of collateral to withdraw * otherwise pass -1 to withdraw maximum amount possible of collateral (including safety factors) * Emits a {Withdraw} event. */ function withdrawLiq(int256 _withdrawAmount) external override nonReentrant onlyFliquidator { // Logic used when called by Fliquidator _withdraw(uint256(_withdrawAmount), address(activeProvider)); IERC20Upgradeable(vAssets.collateralAsset).univTransfer( payable(msg.sender), uint256(_withdrawAmount) ); } /** * @dev Borrows Vault's type underlying amount from activeProvider * @param _borrowAmount: token amount of underlying to borrow * Emits a {Borrow} event. */ function borrow(uint256 _borrowAmount) public override nonReentrant { updateF1155Balances(); _internalBorrow(_borrowAmount); } /** * @dev Paybacks Vault's type underlying to activeProvider - called by users * @param _repayAmount: token amount of underlying to repay, or * pass any 'negative number' to repay full ammount * Emits a {Repay} event. */ function payback(int256 _repayAmount) public payable override { updateF1155Balances(); _internalPayback(_repayAmount); } /** * @dev Paybacks Vault's type underlying to activeProvider * @param _repayAmount: token amount of underlying to repay, or pass -1 to repay full ammount * Emits a {Repay} event. */ function paybackLiq(address[] memory _users, uint256 _repayAmount) external payable override onlyFliquidator { // calculate protocol fee uint256 _fee = 0; for (uint256 i = 0; i < _users.length; i++) { if (_users[i] != address(0)) { _userFeeTimestamps[_users[i]] = block.timestamp; uint256 debtPrincipal = IFujiERC1155(fujiERC1155).balanceOf(_users[i], vAssets.borrowID); _fee += _userProtocolFee(_users[i], debtPrincipal); } } // Logic used when called by Fliquidator _payback(_repayAmount - _fee, address(activeProvider)); // Update protocol fees remainingProtocolFee += _fee; } /** * @dev Changes Vault debt and collateral to newProvider, called by Flasher * @param _newProvider new provider's address * @param _flashLoanAmount amount of flashloan underlying to repay Flashloan * Emits a {Switch} event. */ function executeSwitch( address _newProvider, uint256 _flashLoanAmount, uint256 _fee ) external payable override onlyFlash whenNotPaused { // Check '_newProvider' is a valid provider bool validProvider; for (uint256 i = 0; i < providers.length; i++) { if (_newProvider == providers[i]) { validProvider = true; } } if (!validProvider) { revert(Errors.VL_INVALID_NEW_PROVIDER); } // Compute Ratio of transfer before payback uint256 ratio = (_flashLoanAmount * 1e18) / (IProvider(activeProvider).getBorrowBalance(vAssets.borrowAsset)); // Payback current provider _payback(_flashLoanAmount, activeProvider); // Withdraw collateral proportional ratio from current provider uint256 collateraltoMove = (IProvider(activeProvider).getDepositBalance( vAssets.collateralAsset ) * ratio) / 1e18; _withdraw(collateraltoMove, activeProvider); // Deposit to the new provider _deposit(collateraltoMove, _newProvider); // Borrow from the new provider, borrowBalance + premium _borrow(_flashLoanAmount + _fee, _newProvider); // return borrowed amount to Flasher IERC20Upgradeable(vAssets.borrowAsset).univTransfer( payable(msg.sender), _flashLoanAmount + _fee ); emit Switch(activeProvider, _newProvider, _flashLoanAmount, collateraltoMove); } // Setter, change state functions /** * @dev Sets the fujiAdmin Address * @param _newFujiAdmin: FujiAdmin Contract Address * Emits a {FujiAdminChanged} event. */ function setFujiAdmin(address _newFujiAdmin) external onlyOwner { require(_newFujiAdmin != address(0), Errors.VL_ZERO_ADDR); _fujiAdmin = IFujiAdmin(_newFujiAdmin); emit FujiAdminChanged(_newFujiAdmin); } /** * @dev Sets a new active provider for the Vault * @param _provider: fuji address of the new provider * Emits a {SetActiveProvider} event. */ function setActiveProvider(address _provider) external override isAuthorized { require(_provider != address(0), Errors.VL_ZERO_ADDR); activeProvider = _provider; emit SetActiveProvider(_provider); } // Administrative functions /** * @dev Sets a fujiERC1155 Collateral and Debt Asset manager for this vault and initializes it. * @param _fujiERC1155: fuji ERC1155 address * Emits a {F1155Changed} event. */ function setFujiERC1155(address _fujiERC1155) external isAuthorized { require(_fujiERC1155 != address(0), Errors.VL_ZERO_ADDR); fujiERC1155 = _fujiERC1155; vAssets.collateralID = IFujiERC1155(_fujiERC1155).addInitializeAsset( IFujiERC1155.AssetType.collateralToken, address(this) ); vAssets.borrowID = IFujiERC1155(_fujiERC1155).addInitializeAsset( IFujiERC1155.AssetType.debtToken, address(this) ); emit F1155Changed(_fujiERC1155); } /** * @dev Set Factors "a" and "b" for a Struct Factor. * @param _newFactorA: Nominator * @param _newFactorB: Denominator * @param _type: 0 for "safetyF", 1 for "collatF", 2 for "protocolFee", 3 for "bonusLiqF" * Emits a {FactorChanged} event. * Requirements: * - _newFactorA and _newFactorB should be non-zero values. * - For safetyF; a/b, should be > 1. * - For collatF; a/b, should be > 1. * - For bonusLiqF; a/b should be < 1. * - For protocolFee; a/b should be < 1. */ function setFactor( uint64 _newFactorA, uint64 _newFactorB, FactorType _type ) external isAuthorized { if (_type == FactorType.Safety) { require(_newFactorA > _newFactorB, Errors.RF_INVALID_RATIO_VALUES); safetyF.a = _newFactorA; safetyF.b = _newFactorB; } else if (_type == FactorType.Collateralization) { require(_newFactorA > _newFactorB, Errors.RF_INVALID_RATIO_VALUES); collatF.a = _newFactorA; collatF.b = _newFactorB; } else if (_type == FactorType.ProtocolFee) { require(_newFactorA < _newFactorB, Errors.RF_INVALID_RATIO_VALUES); protocolFee.a = _newFactorA; protocolFee.b = _newFactorB; } else if (_type == FactorType.BonusLiquidation) { require(_newFactorA < _newFactorB, Errors.RF_INVALID_RATIO_VALUES); bonusLiqF.a = _newFactorA; bonusLiqF.b = _newFactorB; } else { revert(Errors.VL_INVALID_FACTOR); } emit FactorChanged(_type, _newFactorA, _newFactorB); } /** * @dev Sets the Oracle address (Must Comply with AggregatorV3Interface) * @param _oracle: new Oracle address * Emits a {OracleChanged} event. */ function setOracle(address _oracle) external isAuthorized { require(_oracle != address(0), Errors.VL_ZERO_ADDR); oracle = IFujiOracle(_oracle); emit OracleChanged(_oracle); } /** * @dev Sets the NFT Bond Logic address * @param _nftgame: new NFT Game address * Emits a {OracleChanged} event. */ function setNFTGame(address _nftgame) external isAuthorized { require(_nftgame != address(0), Errors.VL_ZERO_ADDR); nftGame = _nftgame; emit NFTGameChanged(_nftgame); } /** * @dev Set providers to the Vault * @param _providers: new providers' addresses * Emits a {ProvidersChanged} event. */ function setProviders(address[] calldata _providers) external isAuthorized { for (uint256 i = 0; i < _providers.length; i++) { require(_providers[i] != address(0), Errors.VL_ZERO_ADDR); } providers = _providers; emit ProvidersChanged(_providers); } /** * @dev External Function to call updateState in F1155 */ function updateF1155Balances() public override { IFujiERC1155(fujiERC1155).updateState( vAssets.borrowID, IProvider(activeProvider).getBorrowBalance(vAssets.borrowAsset) ); IFujiERC1155(fujiERC1155).updateState( vAssets.collateralID, IProvider(activeProvider).getDepositBalance(vAssets.collateralAsset) ); } //Getter Functions /** * @dev Returns an array of the Vault's providers */ function getProviders() external view override returns (address[] memory) { return providers; } /** * @dev Returns an amount to be paid as bonus for liquidation * @param _amount: Vault underlying type intended to be liquidated */ function getLiquidationBonusFor(uint256 _amount) external view override returns (uint256) { return (_amount * bonusLiqF.a) / bonusLiqF.b; } /** * @dev Returns the amount of collateral needed, including or not safety factors * @param _amount: Vault underlying type intended to be borrowed * @param _withFactors: Inidicate if computation should include safety_Factors */ function getNeededCollateralFor(uint256 _amount, bool _withFactors) public view override returns (uint256) { // Get exchange rate uint256 price = oracle.getPriceOf( vAssets.collateralAsset, vAssets.borrowAsset, _collateralAssetDecimals ); uint256 minimumReq = (_amount * price) / (10**uint256(_borrowAssetDecimals)); if (_withFactors) { return (minimumReq * (collatF.a) * (safetyF.a)) / (collatF.b) / (safetyF.b); } else { return minimumReq; } } /** * @dev Returns the borrow balance of the Vault's underlying at a particular provider * @param _provider: address of a provider */ function borrowBalance(address _provider) external view override returns (uint256) { return IProvider(_provider).getBorrowBalance(vAssets.borrowAsset); } /** * @dev Returns the deposit balance of the Vault's type collateral at a particular provider * @param _provider: address of a provider */ function depositBalance(address _provider) external view override returns (uint256) { return IProvider(_provider).getDepositBalance(vAssets.collateralAsset); } /** * @dev Returns the total debt of a user * @param _user: address of a user * @return the total debt of a user including the protocol fee */ function userDebtBalance(address _user) external view override returns (uint256) { uint256 debtPrincipal = IFujiERC1155(fujiERC1155).balanceOf(_user, vAssets.borrowID); uint256 fee = (debtPrincipal * (block.timestamp - _userFeeTimestamps[_user]) * protocolFee.a) / protocolFee.b / ONE_YEAR; return debtPrincipal + fee; } /** * @dev Returns the protocol fee of a user * @param _user: address of a user * @return the protocol fee of a user */ function userProtocolFee(address _user) external view override returns (uint256) { uint256 debtPrincipal = IFujiERC1155(fujiERC1155).balanceOf(_user, vAssets.borrowID); return _userProtocolFee(_user, debtPrincipal); } /** * @dev Returns the collateral asset balance of a user * @param _user: address of a user * @return the collateral asset balance */ function userDepositBalance(address _user) external view override returns (uint256) { return IFujiERC1155(fujiERC1155).balanceOf(_user, vAssets.collateralID); } /** * @dev Harvests the Rewards from baseLayer Protocols * @param _farmProtocolNum: number per VaultHarvester Contract for specific farm * @param _data: the additional data to be used for harvest */ function harvestRewards(uint256 _farmProtocolNum, bytes memory _data) external onlyOwner { (address tokenReturned, IHarvester.Transaction memory harvestTransaction) = IHarvester( _fujiAdmin.getVaultHarvester() ).getHarvestTransaction(_farmProtocolNum, _data); // Claim rewards (bool success, ) = harvestTransaction.to.call(harvestTransaction.data); require(success, "failed to harvest rewards"); if (tokenReturned != address(0)) { uint256 tokenBal = IERC20Upgradeable(tokenReturned).univBalanceOf(address(this)); require(tokenReturned != address(0) && tokenBal > 0, Errors.VL_HARVESTING_FAILED); ISwapper.Transaction memory swapTransaction = ISwapper(_fujiAdmin.getSwapper()) .getSwapTransaction(tokenReturned, vAssets.collateralAsset, tokenBal); // Approve rewards if (tokenReturned != FTM) { IERC20Upgradeable(tokenReturned).univApprove(swapTransaction.to, tokenBal); } // Swap rewards -> collateralAsset (success, ) = swapTransaction.to.call{ value: swapTransaction.value }(swapTransaction.data); require(success, "failed to swap rewards"); _deposit( IERC20Upgradeable(vAssets.collateralAsset).univBalanceOf(address(this)), address(activeProvider) ); updateF1155Balances(); } } /** * @dev Withdraws all the collected Fuji fees in this vault. * NOTE: Fuji fee is charged to all users * as a service for the loan cost optimization. * It is a percentage (defined in 'protocolFee') on top of the users 'debtPrincipal'. * Requirements: * - Must send all fees amount collected to the Fuji treasury. */ function withdrawProtocolFee() external nonReentrant { IERC20Upgradeable(vAssets.borrowAsset).univTransfer( payable(IFujiAdmin(_fujiAdmin).getTreasury()), remainingProtocolFee ); remainingProtocolFee = 0; } // Internal Functions /** * @dev Returns de amount of accrued of Fuji fee by user. * @param _user: user to whom Fuji fee will be computed. * @param _debtPrincipal: current user's debt. */ function _userProtocolFee(address _user, uint256 _debtPrincipal) internal view returns (uint256) { return (_debtPrincipal * (block.timestamp - _userFeeTimestamps[_user]) * protocolFee.a) / protocolFee.b / ONE_YEAR; } /** * @dev Internal function handling logic for {deposit} without 'updateState' call * See {deposit} */ function _internalDeposit(uint256 _collateralAmount) internal { if (vAssets.collateralAsset == FTM) { require(msg.value == _collateralAmount && _collateralAmount != 0, Errors.VL_AMOUNT_ERROR); } else { require(_collateralAmount != 0, Errors.VL_AMOUNT_ERROR); IERC20Upgradeable(vAssets.collateralAsset).safeTransferFrom( msg.sender, address(this), _collateralAmount ); } // Delegate Call Deposit to current provider _deposit(_collateralAmount, address(activeProvider)); // Collateral Management IFujiERC1155(fujiERC1155).mint(msg.sender, vAssets.collateralID, _collateralAmount); emit Deposit(msg.sender, vAssets.collateralAsset, _collateralAmount); } /** * @dev Internal function handling logic for {withdraw} without 'updateState' call * See {withdraw} */ function _internalWithdraw(int256 _withdrawAmount) internal { // Get User Collateral in this Vault uint256 providedCollateral = IFujiERC1155(fujiERC1155).balanceOf( msg.sender, vAssets.collateralID ); // Check User has collateral require(providedCollateral > 0, Errors.VL_INVALID_COLLATERAL); // Get Required Collateral with Factors to maintain debt position healthy uint256 neededCollateral = getNeededCollateralFor( IFujiERC1155(fujiERC1155).balanceOf(msg.sender, vAssets.borrowID), true ); uint256 amountToWithdraw = _withdrawAmount < 0 ? providedCollateral - neededCollateral : uint256(_withdrawAmount); // Check Withdrawal amount, and that it will not fall undercollaterized. require( amountToWithdraw != 0 && providedCollateral - amountToWithdraw >= neededCollateral, Errors.VL_INVALID_WITHDRAW_AMOUNT ); // Collateral Management before Withdraw Operation IFujiERC1155(fujiERC1155).burn(msg.sender, vAssets.collateralID, amountToWithdraw); // Delegate Call Withdraw to current provider _withdraw(amountToWithdraw, address(activeProvider)); // Transer Assets to User IERC20Upgradeable(vAssets.collateralAsset).univTransfer(payable(msg.sender), amountToWithdraw); emit Withdraw(msg.sender, vAssets.collateralAsset, amountToWithdraw); } /** * @dev Internal function handling logic for {borrow} without 'updateState' call * See {borrow} */ function _internalBorrow(uint256 _borrowAmount) internal { uint256 providedCollateral = IFujiERC1155(fujiERC1155).balanceOf( msg.sender, vAssets.collateralID ); uint256 debtPrincipal = IFujiERC1155(fujiERC1155).balanceOf(msg.sender, vAssets.borrowID); uint256 totalBorrow = _borrowAmount + debtPrincipal; // Get Required Collateral with Factors to maintain debt position healthy uint256 neededCollateral = getNeededCollateralFor(totalBorrow, true); // Check Provided Collateral is not Zero, and greater than needed to maintain healthy position require( _borrowAmount != 0 && providedCollateral > neededCollateral, Errors.VL_INVALID_BORROW_AMOUNT ); // Update timestamp for fee calculation uint256 userFee = (debtPrincipal * (block.timestamp - _userFeeTimestamps[msg.sender]) * protocolFee.a) / protocolFee.b / ONE_YEAR; _userFeeTimestamps[msg.sender] = block.timestamp - (userFee * ONE_YEAR * protocolFee.a) / protocolFee.b / totalBorrow; // Debt Management IFujiERC1155(fujiERC1155).mint(msg.sender, vAssets.borrowID, _borrowAmount); // Delegate Call Borrow to current provider _borrow(_borrowAmount, address(activeProvider)); // Transer Assets to User IERC20Upgradeable(vAssets.borrowAsset).univTransfer(payable(msg.sender), _borrowAmount); emit Borrow(msg.sender, vAssets.borrowAsset, _borrowAmount); _afterDebtActionCallback(_borrowAmount, false); } /** * @dev Internal function handling logic for {payback} without 'updateState' call * See {payback} */ function _internalPayback(int256 _repayAmount) internal { uint256 debtBalance = IFujiERC1155(fujiERC1155).balanceOf(msg.sender, vAssets.borrowID); uint256 userFee = _userProtocolFee(msg.sender, debtBalance); // Check User Debt is greater than Zero and amount is not Zero require(uint256(_repayAmount) > userFee && debtBalance > 0, Errors.VL_NO_DEBT_TO_PAYBACK); // If passed argument amount is negative do MAX uint256 amountToPayback = _repayAmount < 0 ? debtBalance + userFee : uint256(_repayAmount); if (vAssets.borrowAsset == FTM) { require(msg.value >= amountToPayback, Errors.VL_AMOUNT_ERROR); if (msg.value > amountToPayback) { IERC20Upgradeable(vAssets.borrowAsset).univTransfer( payable(msg.sender), msg.value - amountToPayback ); } } else { // Check User Allowance require( IERC20Upgradeable(vAssets.borrowAsset).allowance(msg.sender, address(this)) >= amountToPayback, Errors.VL_MISSING_ERC20_ALLOWANCE ); // Transfer Asset from User to Vault IERC20Upgradeable(vAssets.borrowAsset).safeTransferFrom( msg.sender, address(this), amountToPayback ); } // Delegate Call Payback to current provider _payback(amountToPayback - userFee, address(activeProvider)); // Debt Management IFujiERC1155(fujiERC1155).burn(msg.sender, vAssets.borrowID, amountToPayback - userFee); // Update protocol fees _userFeeTimestamps[msg.sender] = block.timestamp; remainingProtocolFee += userFee; emit Payback(msg.sender, vAssets.borrowAsset, debtBalance); _afterDebtActionCallback(amountToPayback, true); } /** * @dev Internal hook function after a 'borrow()' or 'payback()' call. * Used to plug functionality. */ function _afterDebtActionCallback(uint256 _amount, bool _isPayback) internal { if (nftGame != address(0)) { INFTGame game = INFTGame(nftGame); if (block.timestamp < game.gamePhaseTimestamps(1) && block.timestamp >= game.gamePhaseTimestamps(0) && game.isValidVault(address(this))) { game.checkStateOfPoints(msg.sender, _amount, _isPayback, _borrowAssetDecimals); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` 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 amount ) external returns (bool); /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20Upgradeable.sol"; import "../../../utils/AddressUpgradeable.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 SafeERC20Upgradeable { using AddressUpgradeable for address; function safeTransfer( IERC20Upgradeable token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20Upgradeable token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20Upgradeable token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @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(IERC20Upgradeable 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, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
pragma solidity >=0.6.2; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "../../interfaces/IVaultControl.sol"; import "../../libraries/Errors.sol"; /** * @dev Contract that is inherited by FujiVaults * contains delegate call functions to providers and {Pausable} guards * */ abstract contract VaultControlUpgradeable is OwnableUpgradeable, PausableUpgradeable { // Vault Struct for Managed Assets IVaultControl.VaultAssets public vAssets; // Pause Functions /** * @dev Emergency Call to stop all basic money flow functions. */ function pause() public onlyOwner { _pause(); } /** * @dev Emergency Call to stop all basic money flow functions. */ function unpause() public onlyOwner { _unpause(); } } contract VaultBaseUpgradeable is VaultControlUpgradeable { using AddressUpgradeable for address; // Internal functions /** * @dev Executes deposit operation with delegatecall. * @param _amount: amount to be deposited * @param _provider: address of provider to be used */ function _deposit(uint256 _amount, address _provider) internal { bytes memory data = abi.encodeWithSignature( "deposit(address,uint256)", vAssets.collateralAsset, _amount ); _execute(_provider, data); } /** * @dev Executes withdraw operation with delegatecall. * @param _amount: amount to be withdrawn * @param _provider: address of provider to be used */ function _withdraw(uint256 _amount, address _provider) internal { bytes memory data = abi.encodeWithSignature( "withdraw(address,uint256)", vAssets.collateralAsset, _amount ); _execute(_provider, data); } /** * @dev Executes borrow operation with delegatecall. * @param _amount: amount to be borrowed * @param _provider: address of provider to be used */ function _borrow(uint256 _amount, address _provider) internal { bytes memory data = abi.encodeWithSignature( "borrow(address,uint256)", vAssets.borrowAsset, _amount ); _execute(_provider, data); } /** * @dev Executes payback operation with delegatecall. * @param _amount: amount to be paid back * @param _provider: address of provider to be used */ function _payback(uint256 _amount, address _provider) internal { bytes memory data = abi.encodeWithSignature( "payback(address,uint256)", vAssets.borrowAsset, _amount ); _execute(_provider, data); } /** * @dev Returns byte response of delegatcalls */ function _execute(address _target, bytes memory _data) private whenNotPaused returns (bytes memory response) { // This is the same logic of functionDelegateCall provided by openzeppelin. // We copy the code here because of oz-upgrades-unsafe-allow for delegatecall. require(_target.isContract(), Errors.VL_NOT_A_CONTRACT); /// @custom:oz-upgrades-unsafe-allow delegatecall (bool success, bytes memory returndata) = _target.delegatecall(_data); return AddressUpgradeable.verifyCallResult(success, returndata, "delegate call to provider failed"); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IVault { // Vault Events /** * @dev Log a deposit transaction done by a user */ event Deposit(address indexed userAddrs, address indexed asset, uint256 amount); /** * @dev Log a withdraw transaction done by a user */ event Withdraw(address indexed userAddrs, address indexed asset, uint256 amount); /** * @dev Log a borrow transaction done by a user */ event Borrow(address indexed userAddrs, address indexed asset, uint256 amount); /** * @dev Log a payback transaction done by a user */ event Payback(address indexed userAddrs, address indexed asset, uint256 amount); /** * @dev Log a switch from provider to new provider in vault */ event Switch( address fromProviderAddrs, address toProviderAddr, uint256 debtamount, uint256 collattamount ); /** * @dev Log a change in active provider */ event SetActiveProvider(address newActiveProviderAddress); /** * @dev Log a change in the array of provider addresses */ event ProvidersChanged(address[] newProviderArray); /** * @dev Log a change in F1155 address */ event F1155Changed(address newF1155Address); /** * @dev Log a change in fuji admin address */ event FujiAdminChanged(address newFujiAdmin); /** * @dev Log a change in the factor values */ event FactorChanged(FactorType factorType, uint64 newFactorA, uint64 newFactorB); /** * @dev Log a change in the oracle address */ event OracleChanged(address newOracle); enum FactorType { Safety, Collateralization, ProtocolFee, BonusLiquidation } struct Factor { uint64 a; uint64 b; } // Core Vault Functions function deposit(uint256 _collateralAmount) external payable; function withdraw(int256 _withdrawAmount) external; function withdrawLiq(int256 _withdrawAmount) external; function borrow(uint256 _borrowAmount) external; function payback(int256 _repayAmount) external payable; function paybackLiq(address[] memory _users, uint256 _repayAmount) external payable; function executeSwitch( address _newProvider, uint256 _flashLoanDebt, uint256 _fee ) external payable; //Getter Functions function activeProvider() external view returns (address); function borrowBalance(address _provider) external view returns (uint256); function depositBalance(address _provider) external view returns (uint256); function userDebtBalance(address _user) external view returns (uint256); function userProtocolFee(address _user) external view returns (uint256); function userDepositBalance(address _user) external view returns (uint256); function getNeededCollateralFor(uint256 _amount, bool _withFactors) external view returns (uint256); function getLiquidationBonusFor(uint256 _amount) external view returns (uint256); function getProviders() external view returns (address[] memory); function fujiERC1155() external view returns (address); //Setter Functions function setActiveProvider(address _provider) external; function updateF1155Balances() external; function protocolFee() external view returns (uint64, uint64); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IHarvester { struct Transaction { address to; bytes data; } function getHarvestTransaction(uint256 _farmProtocolNum, bytes memory _data) external returns (address claimedToken, Transaction memory transaction); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ISwapper { struct Transaction { address to; bytes data; uint256 value; } function getSwapTransaction( address assetFrom, address assetTo, uint256 amount ) external returns (Transaction memory transaction); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IERC20Extended { function symbol() external view returns (string memory); function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); // getRoundData and latestRoundData should both raise "No data present" // if they do not have data to report, instead of returning unset values // which could be misinterpreted as actual reported values. function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IFujiAdmin { // FujiAdmin Events /** * @dev Log change of flasher address */ event FlasherChanged(address newFlasher); /** * @dev Log change of fliquidator address */ event FliquidatorChanged(address newFliquidator); /** * @dev Log change of treasury address */ event TreasuryChanged(address newTreasury); /** * @dev Log change of controller address */ event ControllerChanged(address newController); /** * @dev Log change of vault harvester address */ event VaultHarvesterChanged(address newHarvester); /** * @dev Log change of swapper address */ event SwapperChanged(address newSwapper); /** * @dev Log change of vault address permission */ event VaultPermitChanged(address vaultAddress, bool newPermit); function validVault(address _vaultAddr) external view returns (bool); function getFlasher() external view returns (address); function getFliquidator() external view returns (address); function getController() external view returns (address); function getTreasury() external view returns (address payable); function getVaultHarvester() external view returns (address); function getSwapper() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IFujiOracle { // FujiOracle Events /** * @dev Log a change in price feed address for asset address */ event AssetPriceFeedChanged(address asset, address newPriceFeedAddress); function getPriceOf( address _collateralAsset, address _borrowAsset, uint8 _decimals ) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IFujiERC1155 { //Asset Types enum AssetType { //uint8 = 0 collateralToken, //uint8 = 1 debtToken } //General Getter Functions function getAssetID(AssetType _type, address _assetAddr) external view returns (uint256); function qtyOfManagedAssets() external view returns (uint64); function balanceOf(address _account, uint256 _id) external view returns (uint256); // function splitBalanceOf(address account,uint256 _AssetID) external view returns (uint256,uint256); // function balanceOfBatchType(address account, AssetType _Type) external view returns (uint256); //Permit Controlled Functions function mint( address _account, uint256 _id, uint256 _amount ) external; function burn( address _account, uint256 _id, uint256 _amount ) external; function updateState(uint256 _assetID, uint256 _newBalance) external; function addInitializeAsset(AssetType _type, address _addr) external returns (uint64); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IProvider { //Basic Core Functions function deposit(address _collateralAsset, uint256 _collateralAmount) external payable; function borrow(address _borrowAsset, uint256 _borrowAmount) external payable; function withdraw(address _collateralAsset, uint256 _collateralAmount) external payable; function payback(address _borrowAsset, uint256 _borrowAmount) external payable; // returns the borrow annualized rate for an asset in ray (1e27) //Example 8.5% annual interest = 0.085 x 10^27 = 85000000000000000000000000 or 85*(10**24) function getBorrowRateFor(address _asset) external view returns (uint256); function getBorrowBalance(address _asset) external view returns (uint256); function getDepositBalance(address _asset) external view returns (uint256); function getBorrowBalanceOf(address _asset, address _who) external returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Errors library * @author Fuji * @notice Defines the error messages emitted by the different contracts * @dev Error messages prefix glossary: * - VL = Validation Logic 100 series * - MATH = Math libraries 200 series * - RF = Refinancing 300 series * - VLT = vault 400 series * - SP = Special 900 series */ library Errors { //Errors string public constant VL_INDEX_OVERFLOW = "100"; // index overflows uint128 string public constant VL_INVALID_MINT_AMOUNT = "101"; //invalid amount to mint string public constant VL_INVALID_BURN_AMOUNT = "102"; //invalid amount to burn string public constant VL_AMOUNT_ERROR = "103"; //Input value >0, and for ETH msg.value and amount shall match string public constant VL_INVALID_WITHDRAW_AMOUNT = "104"; //Withdraw amount exceeds provided collateral, or falls undercollaterized string public constant VL_INVALID_BORROW_AMOUNT = "105"; //Borrow amount does not meet collaterization string public constant VL_NO_DEBT_TO_PAYBACK = "106"; //Msg sender has no debt amount to be payback string public constant VL_MISSING_ERC20_ALLOWANCE = "107"; //Msg sender has not approved ERC20 full amount to transfer string public constant VL_USER_NOT_LIQUIDATABLE = "108"; //User debt position is not liquidatable string public constant VL_DEBT_LESS_THAN_AMOUNT = "109"; //User debt is less than amount to partial close string public constant VL_PROVIDER_ALREADY_ADDED = "110"; // Provider is already added in Provider Array string public constant VL_NOT_AUTHORIZED = "111"; //Not authorized string public constant VL_INVALID_COLLATERAL = "112"; //There is no Collateral, or Collateral is not in active in vault string public constant VL_NO_ERC20_BALANCE = "113"; //User does not have ERC20 balance string public constant VL_INPUT_ERROR = "114"; //Check inputs. For ERC1155 batch functions, array sizes should match. string public constant VL_ASSET_EXISTS = "115"; //Asset intended to be added already exists in FujiERC1155 string public constant VL_ZERO_ADDR_1155 = "116"; //ERC1155: balance/transfer for zero address string public constant VL_NOT_A_CONTRACT = "117"; //Address is not a contract. string public constant VL_INVALID_ASSETID_1155 = "118"; //ERC1155 Asset ID is invalid. string public constant VL_NO_ERC1155_BALANCE = "119"; //ERC1155: insufficient balance for transfer. string public constant VL_MISSING_ERC1155_APPROVAL = "120"; //ERC1155: transfer caller is not owner nor approved. string public constant VL_RECEIVER_REJECT_1155 = "121"; //ERC1155Receiver rejected tokens string public constant VL_RECEIVER_CONTRACT_NON_1155 = "122"; //ERC1155: transfer to non ERC1155Receiver implementer string public constant VL_OPTIMIZER_FEE_SMALL = "123"; //Fuji OptimizerFee has to be > 1 RAY (1e27) string public constant VL_UNDERCOLLATERIZED_ERROR = "124"; // Flashloan-Flashclose cannot be used when User's collateral is worth less than intended debt position to close. string public constant VL_MINIMUM_PAYBACK_ERROR = "125"; // Minimum Amount payback should be at least Fuji Optimizerfee accrued interest. string public constant VL_HARVESTING_FAILED = "126"; // Harvesting Function failed, check provided _farmProtocolNum or no claimable balance. string public constant VL_FLASHLOAN_FAILED = "127"; // Flashloan failed string public constant VL_ERC1155_NOT_TRANSFERABLE = "128"; // ERC1155: Not Transferable string public constant VL_SWAP_SLIPPAGE_LIMIT_EXCEED = "129"; // ERC1155: Not Transferable string public constant VL_ZERO_ADDR = "130"; // Zero Address string public constant VL_INVALID_FLASH_NUMBER = "131"; // invalid flashloan number string public constant VL_INVALID_HARVEST_PROTOCOL_NUMBER = "132"; // invalid flashloan number string public constant VL_INVALID_HARVEST_TYPE = "133"; // invalid flashloan number string public constant VL_INVALID_FACTOR = "134"; // invalid factor string public constant VL_INVALID_NEW_PROVIDER ="135"; // invalid newProvider in executeSwitch string public constant MATH_DIVISION_BY_ZERO = "201"; string public constant MATH_ADDITION_OVERFLOW = "202"; string public constant MATH_MULTIPLICATION_OVERFLOW = "203"; string public constant RF_INVALID_RATIO_VALUES = "301"; // Ratio Value provided is invalid, _ratioA/_ratioB <= 1, and > 0, or activeProvider borrowBalance = 0 string public constant RF_INVALID_NEW_ACTIVEPROVIDER = "302"; //Input '_newProvider' and vault's 'activeProvider' must be different string public constant VLT_CALLER_MUST_BE_VAULT = "401"; // The caller of this function must be a vault string public constant ORACLE_INVALID_LENGTH = "501"; // The assets length and price feeds length doesn't match string public constant ORACLE_NONE_PRICE_FEED = "502"; // The price feed is not found }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import { SafeERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; library LibUniversalERC20UpgradeableFTM { using SafeERC20Upgradeable for IERC20Upgradeable; IERC20Upgradeable private constant _FTM_ADDRESS = IERC20Upgradeable(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF); IERC20Upgradeable private constant _ZERO_ADDRESS = IERC20Upgradeable(0x0000000000000000000000000000000000000000); function isFTM(IERC20Upgradeable token) internal pure returns (bool) { return (token == _ZERO_ADDRESS || token == _FTM_ADDRESS); } function univBalanceOf(IERC20Upgradeable token, address account) internal view returns (uint256) { if (isFTM(token)) { return account.balance; } else { return token.balanceOf(account); } } function univTransfer( IERC20Upgradeable token, address payable to, uint256 amount ) internal { if (amount > 0) { if (isFTM(token)) { (bool sent, ) = to.call{ value: amount }(""); require(sent, "Failed to send Ether"); } else { token.safeTransfer(to, amount); } } } function univApprove( IERC20Upgradeable token, address to, uint256 amount ) internal { require(!isFTM(token), "Approve called on FTM"); if (amount == 0) { token.safeApprove(to, 0); } else { uint256 allowance = token.allowance(address(this), to); if (allowance < amount) { if (allowance > 0) { token.safeApprove(to, 0); } token.safeApprove(to, amount); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface INFTGame { function gamePhaseTimestamps(uint256) external view returns(uint256); function isValidVault(address) external view returns(bool); function checkStateOfPoints( address user, uint256 balanceChange, bool isPayback, uint256 decimals ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; import "../../utils/AddressUpgradeable.sol"; /** * @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. * * 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 initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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://diligence.consensys.net/posts/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.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @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, it is bubbled up by this * function (like regular Solidity function calls). * * 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. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @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`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IVaultControl { struct VaultAssets { address collateralAsset; address borrowAsset; uint64 collateralID; uint64 borrowID; } function vAssets() external view returns (VaultAssets memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
{ "optimizer": { "enabled": true, "runs": 500 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddrs","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Borrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddrs","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newF1155Address","type":"address"}],"name":"F1155Changed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum IVault.FactorType","name":"factorType","type":"uint8"},{"indexed":false,"internalType":"uint64","name":"newFactorA","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"newFactorB","type":"uint64"}],"name":"FactorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newFujiAdmin","type":"address"}],"name":"FujiAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newNFTGame","type":"address"}],"name":"NFTGameChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOracle","type":"address"}],"name":"OracleChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddrs","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Payback","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"newProviderArray","type":"address[]"}],"name":"ProvidersChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newActiveProviderAddress","type":"address"}],"name":"SetActiveProvider","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"fromProviderAddrs","type":"address"},{"indexed":false,"internalType":"address","name":"toProviderAddr","type":"address"},{"indexed":false,"internalType":"uint256","name":"debtamount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collattamount","type":"uint256"}],"name":"Switch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddrs","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"FTM","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activeProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bonusLiqF","outputs":[{"internalType":"uint64","name":"a","type":"uint64"},{"internalType":"uint64","name":"b","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_borrowAmount","type":"uint256"}],"name":"borrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"}],"name":"borrowBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collatF","outputs":[{"internalType":"uint64","name":"a","type":"uint64"},{"internalType":"uint64","name":"b","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_collateralAmount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_collateralAmount","type":"uint256"},{"internalType":"uint256","name":"_borrowAmount","type":"uint256"}],"name":"depositAndBorrow","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"}],"name":"depositBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newProvider","type":"address"},{"internalType":"uint256","name":"_flashLoanAmount","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"executeSwitch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"fujiERC1155","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getLiquidationBonusFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_withFactors","type":"bool"}],"name":"getNeededCollateralFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProviders","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_farmProtocolNum","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"harvestRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fujiadmin","type":"address"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_collateralAsset","type":"address"},{"internalType":"address","name":"_borrowAsset","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftGame","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract IFujiOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"_repayAmount","type":"int256"}],"name":"payback","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"int256","name":"_paybackAmount","type":"int256"},{"internalType":"int256","name":"_collateralAmount","type":"int256"}],"name":"paybackAndWithdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"},{"internalType":"uint256","name":"_repayAmount","type":"uint256"}],"name":"paybackLiq","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"protocolFee","outputs":[{"internalType":"uint64","name":"a","type":"uint64"},{"internalType":"uint64","name":"b","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"providers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"remainingProtocolFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"safetyF","outputs":[{"internalType":"uint64","name":"a","type":"uint64"},{"internalType":"uint64","name":"b","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"}],"name":"setActiveProvider","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_newFactorA","type":"uint64"},{"internalType":"uint64","name":"_newFactorB","type":"uint64"},{"internalType":"enum IVault.FactorType","name":"_type","type":"uint8"}],"name":"setFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newFujiAdmin","type":"address"}],"name":"setFujiAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fujiERC1155","type":"address"}],"name":"setFujiERC1155","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftgame","type":"address"}],"name":"setNFTGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_providers","type":"address[]"}],"name":"setProviders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateF1155Balances","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"userDebtBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"userDepositBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"userProtocolFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vAssets","outputs":[{"internalType":"address","name":"collateralAsset","type":"address"},{"internalType":"address","name":"borrowAsset","type":"address"},{"internalType":"uint64","name":"collateralID","type":"uint64"},{"internalType":"uint64","name":"borrowID","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"_withdrawAmount","type":"int256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int256","name":"_withdrawAmount","type":"int256"}],"name":"withdrawLiq","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawProtocolFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b5061588080620000216000396000f3fe6080604052600436106103165760003560e01c80638456cb591161019a578063b6b55f25116100e1578063e5aa6d051161008a578063f2fde38b11610064578063f2fde38b14610903578063f72dde3014610923578063f8c8765e1461094357600080fd5b8063e5aa6d05146108ae578063e897effb146108c1578063edc922a9146108e157600080fd5b8063cf4f4458116100bb578063cf4f445814610800578063d8df4ce714610813578063df6360a61461088e57600080fd5b8063b6b55f25146107ba578063b75061bb146107cd578063c5ebeaec146107e057600080fd5b8063956501bb11610143578063acb2d4101161011d578063acb2d4101461074f578063aef15ac01461076f578063b0e21e8a1461078f57600080fd5b8063956501bb146106ef57806397f75dd91461070f578063a0add9341461072f57600080fd5b80638da5cb5b116101745780638da5cb5b1461069157806390d7bfae146106af57806391c15432146106cf57600080fd5b80638456cb591461063157806388d4cbb5146106465780638b66aceb1461066657600080fd5b80635c975abb1161025e57806377a7e77d116102075780637dc0d1d0116101e15780637dc0d1d0146105de5780637e62eab8146105fe5780637ec09f9d1461061e57600080fd5b806377a7e77d146105835780637adbf9731461059e5780637c802ff2146105be57600080fd5b80636f1ed6f7116102385780636f1ed6f71461052e578063715018a61461054e57806371e114301461056357600080fd5b80635c975abb146104e057806367ac280a14610503578063685a46051461051857600080fd5b80631c1fc2cc116102c057806350f3fc811161029a57806350f3fc81146104685780635564f53d146104a057806359d8da92146104cb57600080fd5b80631c1fc2cc146103e85780633f4ba83a146104335780634d73e9ba1461044857600080fd5b80631714decd116102f15780631714decd1461039557806319e6e415146103b55780631b98f6ac146103c857600080fd5b8062197ac71461032257806306fdde031461034457806316d3bfbb1461036f57600080fd5b3661031d57005b600080fd5b34801561032e57600080fd5b5061034261033d366004615138565b610963565b005b34801561035057600080fd5b50610359610ac2565b6040516103669190615527565b60405180910390f35b34801561037b57600080fd5b506103876301e1338081565b604051908152602001610366565b3480156103a157600080fd5b506103876103b0366004614e86565b610b50565b6103426103c3366004615138565b610c62565b3480156103d457600080fd5b506103426103e3366004614ff4565b610c76565b3480156103f457600080fd5b5060cd54610413906001600160401b0380821691600160401b90041682565b604080516001600160401b03938416815292909116602083015201610366565b34801561043f57600080fd5b50610342610e45565b34801561045457600080fd5b50610387610463366004614e86565b610ea9565b34801561047457600080fd5b50610488610483366004615138565b610f2f565b6040516001600160a01b039091168152602001610366565b3480156104ac57600080fd5b5060cc54610413906001600160401b0380821691600160401b90041682565b3480156104d757600080fd5b50610342610f59565b3480156104ec57600080fd5b5060655460ff166040519015158152602001610366565b34801561050f57600080fd5b50610342611051565b34801561052457600080fd5b5061038760d85481565b34801561053a57600080fd5b5061034261054936600461529b565b61124b565b34801561055a57600080fd5b50610342611711565b34801561056f57600080fd5b5061034261057e366004614e86565b611775565b34801561058f57600080fd5b506104886001600160a01b0381565b3480156105aa57600080fd5b506103426105b9366004614e86565b6118f6565b3480156105ca57600080fd5b506103876105d9366004614e86565b611a70565b3480156105ea57600080fd5b5060d454610488906001600160a01b031681565b34801561060a57600080fd5b50610342610619366004615138565b611abd565b61034261062c366004615150565b611b26565b34801561063d57600080fd5b50610342611b44565b34801561065257600080fd5b5060d954610488906001600160a01b031681565b34801561067257600080fd5b5060cf54610413906001600160401b0380821691600160401b90041682565b34801561069d57600080fd5b506033546001600160a01b0316610488565b3480156106bb57600080fd5b506103876106ca36600461526c565b611ba6565b3480156106db57600080fd5b506103426106ea366004614e86565b611cd5565b3480156106fb57600080fd5b5061038761070a366004614e86565b611dbf565b34801561071b57600080fd5b5060d154610488906001600160a01b031681565b34801561073b57600080fd5b5061034261074a366004614e86565b611df3565b34801561075b57600080fd5b5060d354610488906001600160a01b031681565b34801561077b57600080fd5b5061034261078a366004615335565b6120ce565b34801561079b57600080fd5b5060ce54610413906001600160401b0380821691600160401b90041682565b6103426107c8366004615138565b6124bd565b6103426107db366004615150565b6124ce565b3480156107ec57600080fd5b506103426107fb366004615138565b6124e8565b61034261080e366004614fc0565b612551565b34801561081f57600080fd5b50609754609854609954610854926001600160a01b0390811692908116916001600160401b03600160a01b9092048216911684565b604080516001600160a01b0395861681529490931660208501526001600160401b0391821692840192909252166060820152608001610366565b34801561089a57600080fd5b506103876108a9366004614e86565b612919565b6103426108bc366004615063565b6129bd565b3480156108cd57600080fd5b506103876108dc366004615138565b612c97565b3480156108ed57600080fd5b506108f6612cc4565b604051610366919061547c565b34801561090f57600080fd5b5061034261091e366004614e86565b612d26565b34801561092f57600080fd5b5061034261093e366004614e86565b612dee565b34801561094f57600080fd5b5061034261095e366004614ebe565b612f68565b6002609a5414156109bb5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002609a5560d25460408051632e1246a160e21b815290516001600160a01b039092169163b8491a8491600480820192602092909190829003018186803b158015610a0557600080fd5b505afa158015610a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3d9190614ea2565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016231313160e81b81525090610a8b5760405162461bcd60e51b81526004016109b29190615527565b5060d154610aa39082906001600160a01b0316613425565b609754610aba906001600160a01b0316338361347e565b506001609a55565b60d58054610acf9061577a565b80601f0160208091040260200160405190810160405280929190818152602001828054610afb9061577a565b8015610b485780601f10610b1d57610100808354040283529160200191610b48565b820191906000526020600020905b815481529060010190602001808311610b2b57829003601f168201915b505050505081565b60d354609954604051627eeac760e11b81526001600160a01b0384811660048301526001600160401b0390921660248201526000928392169062fdd58e9060440160206040518083038186803b158015610ba957600080fd5b505afa158015610bbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be19190615254565b60ce546001600160a01b038516600090815260d76020526040812054929350916301e13380916001600160401b03600160401b8204811692911690610c269042615737565b610c309086615718565b610c3a9190615718565b610c44919061560d565b610c4e919061560d565b9050610c5a81836155f5565b949350505050565b610c6a611051565b610c738161354e565b50565b6033546001600160a01b0316331480610d25575060d260009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cd857600080fd5b505afa158015610cec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d109190614ea2565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b81525090610d5f5760405162461bcd60e51b81526004016109b29190615527565b5060005b81811015610dfa576000838383818110610d8d57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190610da29190614e86565b6001600160a01b031614156040518060400160405280600381526020016203133360ec1b81525090610de75760405162461bcd60e51b81526004016109b29190615527565b5080610df2816157b5565b915050610d63565b50610e0760d08383614d46565b507f32e7fb34fed79bbb365c7c067731ee80348d07c9bb4a54d399d3c389c2fa9a2f8282604051610e3992919061542e565b60405180910390a15050565b6033546001600160a01b03163314610e9f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b2565b610ea76138b6565b565b609854604051637d6af07960e01b81526001600160a01b039182166004820152600091831690637d6af079906024015b60206040518083038186803b158015610ef157600080fd5b505afa158015610f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f299190615254565b92915050565b60d08181548110610f3f57600080fd5b6000918252602090912001546001600160a01b0316905081565b6002609a541415610fac5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b2565b6002609a5560d25460408051631d8cf42560e11b81529051611045926001600160a01b031691633b19e84a916004808301926020929190829003018186803b158015610ff757600080fd5b505afa15801561100b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102f9190614ea2565b60d8546098546001600160a01b0316919061347e565b600060d8556001609a55565b60d35460995460d154609854604051637d6af07960e01b81526001600160a01b03918216600482015293811693635eb62f63936001600160401b0316929190911690637d6af0799060240160206040518083038186803b1580156110b457600080fd5b505afa1580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190615254565b6040516001600160e01b031960e085901b1681526001600160401b0390921660048301526024820152604401600060405180830381600087803b15801561113257600080fd5b505af1158015611146573d6000803e3d6000fd5b505060d35460985460d154609754604051631da0b5cf60e31b81526001600160a01b0391821660048201529381169550635eb62f639450600160a01b9092046001600160401b03169291169063ed05ae789060240160206040518083038186803b1580156111b357600080fd5b505afa1580156111c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111eb9190615254565b6040516001600160e01b031960e085901b1681526001600160401b0390921660048301526024820152604401600060405180830381600087803b15801561123157600080fd5b505af1158015611245573d6000803e3d6000fd5b50505050565b6033546001600160a01b031633146112a55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b2565b60008060d260009054906101000a90046001600160a01b03166001600160a01b03166368f1ecc36040518163ffffffff1660e01b815260040160206040518083038186803b1580156112f657600080fd5b505afa15801561130a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132e9190614ea2565b6001600160a01b0316635e7361e585856040518363ffffffff1660e01b815260040161135b929190615585565b600060405180830381600087803b15801561137557600080fd5b505af1158015611389573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113b19190810190614f19565b91509150600081600001516001600160a01b031682602001516040516113d791906153cf565b6000604051808303816000865af19150503d8060008114611414576040519150601f19603f3d011682016040523d82523d6000602084013e611419565b606091505b505090508061146a5760405162461bcd60e51b815260206004820152601960248201527f6661696c656420746f206861727665737420726577617264730000000000000060448201526064016109b2565b6001600160a01b0383161561170a57600061148e6001600160a01b03851630613952565b90506001600160a01b038416158015906114a85750600081115b6040518060400160405280600381526020016218991b60e91b815250906114e25760405162461bcd60e51b81526004016109b29190615527565b5060d254604080516343ad12af60e01b815290516000926001600160a01b0316916343ad12af916004808301926020929190829003018186803b15801561152857600080fd5b505afa15801561153c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115609190614ea2565b60975460405163dcab1c0360e01b81526001600160a01b03888116600483015291821660248201526044810185905291169063dcab1c0390606401600060405180830381600087803b1580156115b557600080fd5b505af11580156115c9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115f191908101906151b6565b90506001600160a01b038581161461161a57805161161a906001600160a01b03871690846139f3565b80600001516001600160a01b03168160400151826020015160405161163f91906153cf565b60006040518083038185875af1925050503d806000811461167c576040519150601f19603f3d011682016040523d82523d6000602084013e611681565b606091505b505080935050826116d45760405162461bcd60e51b815260206004820152601660248201527f6661696c656420746f207377617020726577617264730000000000000000000060448201526064016109b2565b6097546116ff906116ee906001600160a01b031630613952565b60d1546001600160a01b0316613b1f565b611707611051565b50505b5050505050565b6033546001600160a01b0316331461176b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b2565b610ea76000613b78565b6033546001600160a01b0316331480611824575060d260009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117d757600080fd5b505afa1580156117eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180f9190614ea2565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b8152509061185e5760405162461bcd60e51b81526004016109b29190615527565b5060408051808201909152600381526203133360ec1b60208201526001600160a01b0382166118a05760405162461bcd60e51b81526004016109b29190615527565b5060d180546001600160a01b0319166001600160a01b0383169081179091556040519081527f623e52a82ff2bab02a51be01f76b0b3178bbafcbe15c455b7ca4c9615b8da598906020015b60405180910390a150565b6033546001600160a01b03163314806119a5575060d260009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561195857600080fd5b505afa15801561196c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119909190614ea2565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b815250906119df5760405162461bcd60e51b81526004016109b29190615527565b5060408051808201909152600381526203133360ec1b60208201526001600160a01b038216611a215760405162461bcd60e51b81526004016109b29190615527565b5060d480546001600160a01b0319166001600160a01b0383169081179091556040519081527f0e05ae75e8b926552cf6fcd744d19f422561e3ced1e426868730852702dbe418906020016118eb565b60d354609854604051627eeac760e11b81526001600160a01b038481166004830152600160a01b9092046001600160401b03166024820152600092919091169062fdd58e90604401610ed9565b6002609a541415611b105760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b2565b6002609a55611b1d611051565b610aba81613bca565b611b2e611051565b611b378261354e565b611b4081613bca565b5050565b6033546001600160a01b03163314611b9e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b2565b610ea7613e9d565b60d45460975460985460d65460405163721adea760e01b81526001600160a01b039384166004820152918316602483015260ff1660448201526000928392169063721adea79060640160206040518083038186803b158015611c0757600080fd5b505afa158015611c1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3f9190615254565b60d654909150600090611c5b90610100900460ff16600a615670565b611c658387615718565b611c6f919061560d565b90508315611ccc5760cc5460cd546001600160401b03600160401b80840482169390830482169290821691611ca5911685615718565b611caf9190615718565b611cb9919061560d565b611cc3919061560d565b92505050610f29565b9150610f299050565b6033546001600160a01b03163314611d2f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b2565b60408051808201909152600381526203133360ec1b60208201526001600160a01b038216611d705760405162461bcd60e51b81526004016109b29190615527565b5060d280546001600160a01b0319166001600160a01b0383169081179091556040519081527fa05e64ea7e34b372177317c71229808e25bdbfe5dc3e6bc4fc7ca66c97d93276906020016118eb565b609754604051631da0b5cf60e31b81526001600160a01b03918216600482015260009183169063ed05ae7890602401610ed9565b6033546001600160a01b0316331480611ea2575060d260009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b158015611e5557600080fd5b505afa158015611e69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e8d9190614ea2565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b81525090611edc5760405162461bcd60e51b81526004016109b29190615527565b5060408051808201909152600381526203133360ec1b60208201526001600160a01b038216611f1e5760405162461bcd60e51b81526004016109b29190615527565b5060d380546001600160a01b0319166001600160a01b0383169081179091556040516330e2d1ed60e01b81526330e2d1ed90611f619060009030906004016154c9565b602060405180830381600087803b158015611f7b57600080fd5b505af1158015611f8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb39190615319565b609880546001600160401b0392909216600160a01b027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff9092169190911790556040516330e2d1ed60e01b81526001600160a01b038216906330e2d1ed906120229060019030906004016154c9565b602060405180830381600087803b15801561203c57600080fd5b505af1158015612050573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120749190615319565b6099805467ffffffffffffffff19166001600160401b03929092169190911790556040516001600160a01b03821681527fb89c4162816fee2afc84abac7e339928e379cd5d1d61acadaa52a39ce2650b6b906020016118eb565b6033546001600160a01b031633148061217d575060d260009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561213057600080fd5b505afa158015612144573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121689190614ea2565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b815250906121b75760405162461bcd60e51b81526004016109b29190615527565b5060008160038111156121da57634e487b7160e01b600052602160045260246000fd5b141561225d57816001600160401b0316836001600160401b0316116040518060400160405280600381526020016233303160e81b8152509061222f5760405162461bcd60e51b81526004016109b29190615527565b5060cc80546001600160401b03848116600160401b026001600160801b03199092169086161717905561247d565b600181600381111561227f57634e487b7160e01b600052602160045260246000fd5b141561230257816001600160401b0316836001600160401b0316116040518060400160405280600381526020016233303160e81b815250906122d45760405162461bcd60e51b81526004016109b29190615527565b5060cd80546001600160401b03848116600160401b026001600160801b03199092169086161717905561247d565b600281600381111561232457634e487b7160e01b600052602160045260246000fd5b14156123a757816001600160401b0316836001600160401b0316106040518060400160405280600381526020016233303160e81b815250906123795760405162461bcd60e51b81526004016109b29190615527565b5060ce80546001600160401b03848116600160401b026001600160801b03199092169086161717905561247d565b60038160038111156123c957634e487b7160e01b600052602160045260246000fd5b141561244c57816001600160401b0316836001600160401b0316106040518060400160405280600381526020016233303160e81b8152509061241e5760405162461bcd60e51b81526004016109b29190615527565b5060cf80546001600160401b03848116600160401b026001600160801b03199092169086161717905561247d565b60408051808201825260038152620c4ccd60ea1b6020820152905162461bcd60e51b81526109b29190600401615527565b7f684344b55402a828ac72dba82a6cdde8094ee32955d4c34d290d43d1a70361228184846040516124b0939291906154f5565b60405180910390a1505050565b6124c5611051565b610c7381613f18565b6124d6611051565b6124df82613f18565b611b40816140a6565b6002609a54141561253b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b2565b6002609a55612548611051565b610aba816140a6565b60d260009054906101000a90046001600160a01b03166001600160a01b0316637fabc90b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561259f57600080fd5b505afa1580156125b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d79190614ea2565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016231313160e81b815250906126255760405162461bcd60e51b81526004016109b29190615527565b5060655460ff161561266c5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016109b2565b6000805b60d0548110156126d15760d0818154811061269b57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03868116911614156126bf57600191505b806126c9816157b5565b915050612670565b508061270857604080518082018252600381526231333560e81b6020820152905162461bcd60e51b81526109b29190600401615527565b60d154609854604051637d6af07960e01b81526001600160a01b0391821660048201526000929190911690637d6af0799060240160206040518083038186803b15801561275457600080fd5b505afa158015612768573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278c9190615254565b61279e85670de0b6b3a7640000615718565b6127a8919061560d565b60d1549091506127c29085906001600160a01b03166143f7565b60d154609754604051631da0b5cf60e31b81526001600160a01b039182166004820152600092670de0b6b3a764000092859291169063ed05ae789060240160206040518083038186803b15801561281857600080fd5b505afa15801561282c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128509190615254565b61285a9190615718565b612864919061560d565b60d15490915061287e9082906001600160a01b0316613425565b6128888187613b1f565b61289b61289585876155f5565b87614450565b6128bc336128a986886155f5565b6098546001600160a01b0316919061347e565b60d154604080516001600160a01b03928316815291881660208301528101869052606081018290527f06792f8797628d4ae9a2a9ec4ff047ef0d1f3fca2c413ec76165fd8c5b125bd99060800160405180910390a1505050505050565b60d354609954604051627eeac760e11b81526001600160a01b0384811660048301526001600160401b0390921660248201526000928392169062fdd58e9060440160206040518083038186803b15801561297257600080fd5b505afa158015612986573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129aa9190615254565b90506129b683826144a9565b9392505050565b60d260009054906101000a90046001600160a01b03166001600160a01b031663b8491a846040518163ffffffff1660e01b815260040160206040518083038186803b158015612a0b57600080fd5b505afa158015612a1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a439190614ea2565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016231313160e81b81525090612a915760405162461bcd60e51b81526004016109b29190615527565b506000805b8351811015612c5c5760006001600160a01b0316848281518110612aca57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031614612c4a574260d76000868481518110612b0557634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002081905550600060d360009054906101000a90046001600160a01b03166001600160a01b031662fdd58e868481518110612b7657634e487b7160e01b600052603260045260246000fd5b602090810291909101015160995460405160e084901b6001600160e01b03191681526001600160a01b0390921660048301526001600160401b0316602482015260440160206040518083038186803b158015612bd157600080fd5b505afa158015612be5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c099190615254565b9050612c3c858381518110612c2e57634e487b7160e01b600052603260045260246000fd5b6020026020010151826144a9565b612c4690846155f5565b9250505b80612c54816157b5565b915050612a96565b50612c7b612c6a8284615737565b60d1546001600160a01b03166143f7565b8060d86000828254612c8d91906155f5565b9091555050505050565b60cf546000906001600160401b03600160401b8204811691612cba911684615718565b610f29919061560d565b606060d0805480602002602001604051908101604052809291908181526020018280548015612d1c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612cfe575b5050505050905090565b6033546001600160a01b03163314612d805760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b2565b6001600160a01b038116612de55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109b2565b610c7381613b78565b6033546001600160a01b0316331480612e9d575060d260009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b158015612e5057600080fd5b505afa158015612e64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e889190614ea2565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b81525090612ed75760405162461bcd60e51b81526004016109b29190615527565b5060408051808201909152600381526203133360ec1b60208201526001600160a01b038216612f195760405162461bcd60e51b81526004016109b29190615527565b5060d980546001600160a01b0319166001600160a01b0383169081179091556040519081527f34e83df4a2403449e089f520b489d0789cc98ee337bea3e0ed8f0c097f6632e0906020016118eb565b600054610100900460ff16612f835760005460ff1615612f87565b303b155b612ff95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016109b2565b600054610100900460ff1615801561301b576000805461ffff19166101011790555b6001600160a01b0385161580159061303b57506001600160a01b03841615155b801561304f57506001600160a01b03831615155b801561306357506001600160a01b03821615155b6040518060400160405280600381526020016203133360ec1b8152509061309d5760405162461bcd60e51b81526004016109b29190615527565b506130a6614513565b6130ae614542565b6130b6614571565b60d280546001600160a01b038088166001600160a01b03199283161790925560d48054878416908316179055609780548684169083168117909155609880548685169316929092179091556060918291141561313a5760408051808201909152600381526246544d60e81b602082015260d6805460ff191660121790559150613237565b846001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561317357600080fd5b505afa158015613187573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526131af9190810190615171565b9150846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156131ea57600080fd5b505afa1580156131fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132229190615382565b60d6805460ff191660ff929092169190911790555b6001600160a01b038481161415613277575060408051808201909152600381526246544d60e81b602082015260d6805461ff00191661120017905561337a565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156132b057600080fd5b505afa1580156132c4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132ec9190810190615171565b9050836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561332757600080fd5b505afa15801561333b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061335f9190615382565b60d660016101000a81548160ff021916908360ff1602179055505b818160405160200161338d9291906153eb565b60405160208183030381529060405260d590805190602001906133b1929190614da9565b505060cc80546001600160801b0319908116681400000000000000151790915560cd80548216683f000000000000005017905560cf805482166814000000000000000117905560ce80549091166903e8000000000000000117905550801561170a576000805461ff00191690555050505050565b6097546040516001600160a01b0390911660248201526044810183905260009060640160408051601f198184030181529190526020810180516001600160e01b031663f3fef3a360e01b179052905061124582826145a0565b80156135495761348d836146da565b15613535576000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146134df576040519150601f19603f3d011682016040523d82523d6000602084013e6134e4565b606091505b50509050806112455760405162461bcd60e51b815260206004820152601460248201527f4661696c656420746f2073656e6420457468657200000000000000000000000060448201526064016109b2565b6135496001600160a01b03841683836146fd565b505050565b60d354609954604051627eeac760e11b81523360048201526001600160401b0390911660248201526000916001600160a01b03169062fdd58e9060440160206040518083038186803b1580156135a357600080fd5b505afa1580156135b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135db9190615254565b905060006135e933836144a9565b905080831180156135fa5750600082115b6040518060400160405280600381526020016218981b60e91b815250906136345760405162461bcd60e51b81526004016109b29190615527565b506000808412613644578361364e565b61364e82846155f5565b6098549091506001600160a01b0390811614156136bf57803410156040518060400160405280600381526020016231303360e81b815250906136a35760405162461bcd60e51b81526004016109b29190615527565b50803411156136ba576136ba336128a98334615737565b613795565b609854604051636eb1769f60e11b815233600482015230602482015282916001600160a01b03169063dd62ed3e9060440160206040518083038186803b15801561370857600080fd5b505afa15801561371c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137409190615254565b10156040518060400160405280600381526020016231303760e81b8152509061377c5760405162461bcd60e51b81526004016109b29190615527565b50609854613795906001600160a01b0316333084614760565b6137a2612c6a8383615737565b60d3546099546001600160a01b039091169063f5298aca9033906001600160401b03166137cf8686615737565b6040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526001600160401b0390911660248301526044820152606401600060405180830381600087803b15801561382557600080fd5b505af1158015613839573d6000803e3d6000fd5b505033600090815260d76020526040812042905560d880548694509092506138629084906155f5565b90915550506098546040518481526001600160a01b039091169033907ffc2d2b4b3ad857c1c0893799f86b421efff822709b26de93df5709671f4841ca9060200160405180910390a3611245816001614798565b60655460ff166139085760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016109b2565b6065805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600061395d836146da565b1561397357506001600160a01b03811631610f29565b6040516370a0823160e01b81526001600160a01b0383811660048301528416906370a082319060240160206040518083038186803b1580156139b457600080fd5b505afa1580156139c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ec9190615254565b9050610f29565b6139fc836146da565b15613a495760405162461bcd60e51b815260206004820152601560248201527f417070726f76652063616c6c6564206f6e2046544d000000000000000000000060448201526064016109b2565b80613a63576135496001600160a01b0384168360006149a4565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e9060440160206040518083038186803b158015613aae57600080fd5b505afa158015613ac2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae69190615254565b905081811015611245578015613b0b57613b0b6001600160a01b0385168460006149a4565b6112456001600160a01b03851684846149a4565b6097546040516001600160a01b0390911660248201526044810183905260009060640160408051601f198184030181529190526020810180516001600160e01b03166311f9fbc960e21b179052905061124582826145a0565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60d354609854604051627eeac760e11b8152336004820152600160a01b9091046001600160401b031660248201526000916001600160a01b03169062fdd58e9060440160206040518083038186803b158015613c2557600080fd5b505afa158015613c39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c5d9190615254565b9050600081116040518060400160405280600381526020016218989960e91b81525090613c9d5760405162461bcd60e51b81526004016109b29190615527565b5060d354609954604051627eeac760e11b81523360048201526001600160401b039091166024820152600091613d38916001600160a01b039091169062fdd58e9060440160206040518083038186803b158015613cf957600080fd5b505afa158015613d0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d319190615254565b6001611ba6565b90506000808412613d495783613d53565b613d538284615737565b90508015801590613d6d575081613d6a8285615737565b10155b604051806040016040528060038152602001620c4c0d60ea1b81525090613da75760405162461bcd60e51b81526004016109b29190615527565b5060d354609854604051637a94c56560e11b8152336004820152600160a01b9091046001600160401b03166024820152604481018390526001600160a01b039091169063f5298aca90606401600060405180830381600087803b158015613e0d57600080fd5b505af1158015613e21573d6000803e3d6000fd5b505060d154613e3c92508391506001600160a01b0316613425565b609754613e53906001600160a01b0316338361347e565b6097546040518281526001600160a01b039091169033907f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb9060200160405180910390a350505050565b60655460ff1615613ee35760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016109b2565b6065805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586139353390565b6097546001600160a01b039081161415613f7a578034148015613f3a57508015155b6040518060400160405280600381526020016231303360e81b81525090613f745760405162461bcd60e51b81526004016109b29190615527565b50613fcb565b60408051808201909152600381526231303360e81b602082015281613fb25760405162461bcd60e51b81526004016109b29190615527565b50609754613fcb906001600160a01b0316333084614760565b60d154613fe29082906001600160a01b0316613b1f565b60d354609854604051630ab714fb60e11b8152336004820152600160a01b9091046001600160401b03166024820152604481018390526001600160a01b039091169063156e29f690606401600060405180830381600087803b15801561404757600080fd5b505af115801561405b573d6000803e3d6000fd5b50506097546040518481526001600160a01b0390911692503391507f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f629060200160405180910390a350565b60d354609854604051627eeac760e11b8152336004820152600160a01b9091046001600160401b031660248201526000916001600160a01b03169062fdd58e9060440160206040518083038186803b15801561410157600080fd5b505afa158015614115573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141399190615254565b60d354609954604051627eeac760e11b81523360048201526001600160401b0390911660248201529192506000916001600160a01b039091169062fdd58e9060440160206040518083038186803b15801561419357600080fd5b505afa1580156141a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141cb9190615254565b905060006141d982856155f5565b905060006141e8826001611ba6565b905084158015906141f857508084115b6040518060400160405280600381526020016231303560e81b815250906142325760405162461bcd60e51b81526004016109b29190615527565b5060ce5433600090815260d7602052604081205490916301e13380916001600160401b03600160401b8304811692169061426c9042615737565b6142769088615718565b6142809190615718565b61428a919061560d565b614294919061560d565b60ce5490915083906001600160401b03600160401b8204811691166142bd6301e1338085615718565b6142c79190615718565b6142d1919061560d565b6142db919061560d565b6142e59042615737565b33600081815260d76020526040908190209290925560d3546099549251630ab714fb60e11b815260048101929092526001600160401b039092166024820152604481018890526001600160a01b039091169063156e29f690606401600060405180830381600087803b15801561435a57600080fd5b505af115801561436e573d6000803e3d6000fd5b505060d15461438992508891506001600160a01b0316614450565b6098546143a0906001600160a01b0316338861347e565b6098546040518781526001600160a01b039091169033907f312a5e5e1079f5dda4e95dbbd0b908b291fd5b992ef22073643ab691572c5b529060200160405180910390a36143ef866000614798565b505050505050565b6098546040516001600160a01b0390911660248201526044810183905260009060640160408051601f198184030181529190526020810180516001600160e01b03166306bdb15760e31b179052905061124582826145a0565b6098546040516001600160a01b0390911660248201526044810183905260009060640160408051601f198184030181529190526020810180516001600160e01b0316634b8a352960e01b179052905061124582826145a0565b60ce546001600160a01b038316600090815260d7602052604081205490916301e13380916001600160401b03600160401b830481169216906144eb9042615737565b6144f59086615718565b6144ff9190615718565b614509919061560d565b6129b6919061560d565b600054610100900460ff1661453a5760405162461bcd60e51b81526004016109b29061553a565b610ea7614acf565b600054610100900460ff166145695760405162461bcd60e51b81526004016109b29061553a565b610ea7614aff565b600054610100900460ff166145985760405162461bcd60e51b81526004016109b29061553a565b610ea7614b32565b60606145ae60655460ff1690565b156145ee5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016109b2565b60408051808201909152600381526231313760e81b60208201526001600160a01b0384163b6146305760405162461bcd60e51b81526004016109b29190615527565b50600080846001600160a01b03168460405161464c91906153cf565b600060405180830381855af49150503d8060008114614687576040519150601f19603f3d011682016040523d82523d6000602084013e61468c565b606091505b50915091506146d182826040518060400160405280602081526020017f64656c65676174652063616c6c20746f2070726f7669646572206661696c6564815250614b60565b95945050505050565b60006001600160a01b0382161580610f295750506001600160a01b039081161490565b6040516001600160a01b03831660248201526044810182905261354990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614b99565b6040516001600160a01b03808516602483015283166044820152606481018290526112459085906323b872dd60e01b90608401614729565b60d9546001600160a01b031615611b405760d954604051631f42ad6f60e31b8152600160048201526001600160a01b0390911690819063fa156b789060240160206040518083038186803b1580156147ef57600080fd5b505afa158015614803573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148279190615254565b421080156148ac5750604051631f42ad6f60e31b8152600060048201526001600160a01b0382169063fa156b789060240160206040518083038186803b15801561487057600080fd5b505afa158015614884573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148a89190615254565b4210155b801561492a5750604051630642194560e41b81523060048201526001600160a01b0382169063642194509060240160206040518083038186803b1580156148f257600080fd5b505afa158015614906573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061492a919061511c565b156135495760d6546040516304a59e4560e51b815233600482015260248101859052831515604482015261010090910460ff1660648201526001600160a01b038216906394b3c8a090608401600060405180830381600087803b15801561499057600080fd5b505af1158015611707573d6000803e3d6000fd5b801580614a2d5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156149f357600080fd5b505afa158015614a07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614a2b9190615254565b155b614a9f5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e63650000000000000000000060648201526084016109b2565b6040516001600160a01b03831660248201526044810182905261354990849063095ea7b360e01b90606401614729565b600054610100900460ff16614af65760405162461bcd60e51b81526004016109b29061553a565b610ea733613b78565b600054610100900460ff16614b265760405162461bcd60e51b81526004016109b29061553a565b6065805460ff19169055565b600054610100900460ff16614b595760405162461bcd60e51b81526004016109b29061553a565b6001609a55565b60608315614b6f5750816129b6565b825115614b7f5782518084602001fd5b8160405162461bcd60e51b81526004016109b29190615527565b6000614bee826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614c6b9092919063ffffffff16565b8051909150156135495780806020019051810190614c0c919061511c565b6135495760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109b2565b6060610c5a8484600085856001600160a01b0385163b614ccd5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109b2565b600080866001600160a01b03168587604051614ce991906153cf565b60006040518083038185875af1925050503d8060008114614d26576040519150601f19603f3d011682016040523d82523d6000602084013e614d2b565b606091505b5091509150614d3b828286614b60565b979650505050505050565b828054828255906000526020600020908101928215614d99579160200282015b82811115614d995781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190614d66565b50614da5929150614e1d565b5090565b828054614db59061577a565b90600052602060002090601f016020900481019282614dd75760008555614d99565b82601f10614df057805160ff1916838001178555614d99565b82800160010185558215614d99579182015b82811115614d99578251825591602001919060010190614e02565b5b80821115614da55760008155600101614e1e565b6000614e45614e40846155ce565b61559e565b9050828152838383011115614e5957600080fd5b6129b683602083018461574e565b600082601f830112614e77578081fd5b6129b683835160208501614e32565b600060208284031215614e97578081fd5b81356129b681615812565b600060208284031215614eb3578081fd5b81516129b681615812565b60008060008060808587031215614ed3578283fd5b8435614ede81615812565b93506020850135614eee81615812565b92506040850135614efe81615812565b91506060850135614f0e81615812565b939692955090935050565b60008060408385031215614f2b578081fd5b8251614f3681615812565b60208401519092506001600160401b0380821115614f52578283fd5b9084019060408287031215614f65578283fd5b604051604081018181108382111715614f8057614f806157fc565b6040528251614f8e81615812565b8152602083015182811115614fa1578485fd5b614fad88828601614e67565b6020830152508093505050509250929050565b600080600060608486031215614fd4578081fd5b8335614fdf81615812565b95602085013595506040909401359392505050565b60008060208385031215615006578182fd5b82356001600160401b038082111561501c578384fd5b818501915085601f83011261502f578384fd5b81358181111561503d578485fd5b8660208260051b8501011115615051578485fd5b60209290920196919550909350505050565b60008060408385031215615075578182fd5b82356001600160401b038082111561508b578384fd5b818501915085601f83011261509e578384fd5b81356020828211156150b2576150b26157fc565b8160051b92506150c381840161559e565b8281528181019085830185870184018b10156150dd578889fd5b8896505b8487101561510b57803595506150f686615812565b858352600196909601959183019183016150e1565b509997909101359750505050505050565b60006020828403121561512d578081fd5b81516129b681615827565b600060208284031215615149578081fd5b5035919050565b60008060408385031215615162578182fd5b50508035926020909101359150565b600060208284031215615182578081fd5b81516001600160401b03811115615197578182fd5b8201601f810184136151a7578182fd5b610c5a84825160208401614e32565b6000602082840312156151c7578081fd5b81516001600160401b03808211156151dd578283fd5b90830190606082860312156151f0578283fd5b60405160608101818110838211171561520b5761520b6157fc565b604052825161521981615812565b815260208301518281111561522c578485fd5b61523887828601614e67565b6020830152506040830151604082015280935050505092915050565b600060208284031215615265578081fd5b5051919050565b6000806040838503121561527e578182fd5b82359150602083013561529081615827565b809150509250929050565b600080604083850312156152ad578182fd5b8235915060208301356001600160401b038111156152c9578182fd5b8301601f810185136152d9578182fd5b80356152e7614e40826155ce565b8181528660208385010111156152fb578384fd5b81602084016020830137908101602001929092525090939092509050565b60006020828403121561532a578081fd5b81516129b681615835565b600080600060608486031215615349578081fd5b833561535481615835565b9250602084013561536481615835565b9150604084013560048110615377578182fd5b809150509250925092565b600060208284031215615393578081fd5b815160ff811681146129b6578182fd5b600081518084526153bb81602086016020860161574e565b601f01601f19169290920160200192915050565b600082516153e181846020870161574e565b9190910192915050565b6415985d5b1d60da1b81526000835161540b81600585016020880161574e565b83519083019061542281600584016020880161574e565b01600501949350505050565b60208082528181018390526000908460408401835b8681101561547157823561545681615812565b6001600160a01b031682529183019190830190600101615443565b509695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156154bd5783516001600160a01b031683529284019291840191600101615498565b50909695505050505050565b60408101600284106154dd576154dd6157e6565b9281526001600160a01b039190911660209091015290565b6060810160048510615509576155096157e6565b9381526001600160401b039283166020820152911660409091015290565b6020815260006129b660208301846153a3565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b828152604060208201526000610c5a60408301846153a3565b604051601f8201601f191681016001600160401b03811182821017156155c6576155c66157fc565b604052919050565b60006001600160401b038211156155e7576155e76157fc565b50601f01601f191660200190565b60008219821115615608576156086157d0565b500190565b60008261562857634e487b7160e01b81526012600452602481fd5b500490565b600181815b8085111561566857816000190482111561564e5761564e6157d0565b8085161561565b57918102915b93841c9390800290615632565b509250929050565b60006129b6838360008261568657506001610f29565b8161569357506000610f29565b81600181146156a957600281146156b3576156cf565b6001915050610f29565b60ff8411156156c4576156c46157d0565b50506001821b610f29565b5060208310610133831016604e8410600b84101617156156f2575081810a610f29565b6156fc838361562d565b8060001904821115615710576157106157d0565b029392505050565b6000816000190483118215151615615732576157326157d0565b500290565b600082821015615749576157496157d0565b500390565b60005b83811015615769578181015183820152602001615751565b838111156112455750506000910152565b600181811c9082168061578e57607f821691505b602082108114156157af57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156157c9576157c96157d0565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c7357600080fd5b8015158114610c7357600080fd5b6001600160401b0381168114610c7357600080fdfea2646970667358221220602552cce7f16700832f8113f76a3141844734b643f334ba2db73678424fd55f64736f6c63430008040033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Validator ID :
0 FTM
Amount Staked
0
Amount Delegated
0
Staking Total
0
Staking Start Epoch
0
Staking Start Time
0
Proof of Importance
0
Origination Score
0
Validation Score
0
Active
0
Online
0
Downtime
0 s
Address | Amount | claimed Rewards | Created On Epoch | Created On |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.