Latest 25 from a total of 1,095 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| 0x43757272 | 22980500 | 214 days ago | IN | 0 ETH | 0.00005432 | ||||
| Update F1155Bala... | 21072596 | 480 days ago | IN | 0 ETH | 0.00564214 | ||||
| Withdraw | 21072343 | 481 days ago | IN | 0 ETH | 0.0090202 | ||||
| Payback | 20734435 | 528 days ago | IN | 0 ETH | 0.00216112 | ||||
| Withdraw | 20655959 | 539 days ago | IN | 0 ETH | 0.00033032 | ||||
| Withdraw | 20399987 | 574 days ago | IN | 0 ETH | 0.00204933 | ||||
| Withdraw | 20399954 | 574 days ago | IN | 0.1 ETH | 0.00008373 | ||||
| Withdraw | 20399931 | 574 days ago | IN | 0 ETH | 0.00151342 | ||||
| Withdraw | 20399910 | 574 days ago | IN | 0 ETH | 0.00113267 | ||||
| Withdraw | 20399842 | 574 days ago | IN | 0 ETH | 0.00092458 | ||||
| Withdraw | 20399836 | 574 days ago | IN | 0 ETH | 0.00011521 | ||||
| Payback | 20282823 | 591 days ago | IN | 0 ETH | 0.00176535 | ||||
| Withdraw | 20197082 | 603 days ago | IN | 0 ETH | 0.00096958 | ||||
| Withdraw | 20186958 | 604 days ago | IN | 0 ETH | 0.00280464 | ||||
| Payback | 20157069 | 608 days ago | IN | 0 ETH | 0.00130216 | ||||
| Withdraw | 20127806 | 612 days ago | IN | 0 ETH | 0.00278222 | ||||
| Payback | 20114526 | 614 days ago | IN | 0 ETH | 0.0029501 | ||||
| Withdraw | 20059339 | 622 days ago | IN | 0 ETH | 0.00162902 | ||||
| Payback | 19892027 | 645 days ago | IN | 0 ETH | 0.00168876 | ||||
| Borrow | 19630465 | 682 days ago | IN | 0 ETH | 0.00649872 | ||||
| Borrow | 19630452 | 682 days ago | IN | 0 ETH | 0.00393224 | ||||
| Borrow | 19625211 | 683 days ago | IN | 0 ETH | 0.00866674 | ||||
| Payback | 19616640 | 684 days ago | IN | 0 ETH | 0.00945919 | ||||
| Withdraw | 19517157 | 698 days ago | IN | 0 ETH | 0.00926904 | ||||
| Withdraw | 19517003 | 698 days ago | IN | 0 ETH | 0.00585264 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 21072343 | 481 days ago | 0.0001 ETH | ||||
| Transfer | 21072343 | 481 days ago | 0.0001 ETH | ||||
| Transfer | 20655959 | 539 days ago | 0.00096202 ETH | ||||
| Transfer | 20655959 | 539 days ago | 0.00096202 ETH | ||||
| Transfer | 20197082 | 603 days ago | 0.00452714 ETH | ||||
| Transfer | 20197082 | 603 days ago | 0.00452714 ETH | ||||
| Transfer | 20186958 | 604 days ago | 0.00271083 ETH | ||||
| Transfer | 20186958 | 604 days ago | 0.00271083 ETH | ||||
| Transfer | 20059339 | 622 days ago | 0 ETH | ||||
| Transfer | 20059339 | 622 days ago | 0 ETH | ||||
| Transfer | 19517157 | 698 days ago | 0.082 ETH | ||||
| Transfer | 19517157 | 698 days ago | 0.082 ETH | ||||
| Transfer | 19060085 | 762 days ago | 0.0432 ETH | ||||
| Transfer | 19060085 | 762 days ago | 0.0432 ETH | ||||
| Transfer | 18848250 | 792 days ago | 0.14382945 ETH | ||||
| Transfer | 18848250 | 792 days ago | 0.14382945 ETH | ||||
| Mint | 18842957 | 792 days ago | 0.1 ETH | ||||
| Transfer | 18471525 | 844 days ago | 0.10097361 ETH | ||||
| Transfer | 18471525 | 844 days ago | 0.10097361 ETH | ||||
| Transfer | 18447157 | 848 days ago | 0.08408679 ETH | ||||
| Transfer | 18447157 | 848 days ago | 0.08408679 ETH | ||||
| Transfer | 18402817 | 854 days ago | 0.00665688 ETH | ||||
| Transfer | 18402817 | 854 days ago | 0.00665688 ETH | ||||
| Transfer | 18333237 | 864 days ago | 0.044367 ETH | ||||
| Transfer | 18333237 | 864 days ago | 0.044367 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
VaultETHUSDC
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.25 <0.8.0;
pragma experimental ABIEncoderV2;
import { IVault } from "./IVault.sol";
import { VaultBase } from "./VaultBase.sol";
import { IFujiAdmin } from "../IFujiAdmin.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {
AggregatorV3Interface
} from "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IFujiERC1155 } from "../FujiERC1155/IFujiERC1155.sol";
import { IProvider } from "../Providers/IProvider.sol";
import { IAlphaWhiteList } from "../IAlphaWhiteList.sol";
import { Errors } from "../Libraries/Errors.sol";
interface IVaultHarvester {
function collectRewards(uint256 _farmProtocolNum) external returns (address claimedToken);
}
contract VaultETHUSDC is IVault, VaultBase, ReentrancyGuard {
uint256 internal constant _BASE = 1e18;
struct Factor {
uint64 a;
uint64 b;
}
// Safety factor
Factor public safetyF;
// Collateralization factor
Factor public collatF;
//State variables
address[] public providers;
address public override activeProvider;
IFujiAdmin private _fujiAdmin;
address public override fujiERC1155;
AggregatorV3Interface public oracle;
modifier isAuthorized() {
require(
msg.sender == owner() || msg.sender == _fujiAdmin.getController(),
Errors.VL_NOT_AUTHORIZED
);
_;
}
modifier onlyFlash() {
require(msg.sender == _fujiAdmin.getFlasher(), Errors.VL_NOT_AUTHORIZED);
_;
}
constructor() public {
vAssets.collateralAsset = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); // ETH
vAssets.borrowAsset = address(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48); // USDC
// 1.05
safetyF.a = 21;
safetyF.b = 20;
// 1.269
collatF.a = 80;
collatF.b = 63;
}
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 {
deposit(_collateralAmount);
borrow(_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 {
payback(_paybackAmount);
withdraw(_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 {
require(msg.value == _collateralAmount && _collateralAmount != 0, Errors.VL_AMOUNT_ERROR);
// Alpha Whitelist Routine
require(
IAlphaWhiteList(_fujiAdmin.getaWhiteList()).whiteListRoutine(
msg.sender,
vAssets.collateralID,
_collateralAmount,
fujiERC1155
),
Errors.SP_ALPHA_WHITELIST
);
// 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 Withdraws Vault's type collateral from activeProvider
* call Controller checkrates
* @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 withdraw(int256 _withdrawAmount) public override nonReentrant {
// If call from Normal User do typical, otherwise Fliquidator
if (msg.sender != _fujiAdmin.getFliquidator()) {
updateF1155Balances();
// 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.sub(neededCollateral) : uint256(_withdrawAmount);
// Check Withdrawal amount, and that it will not fall undercollaterized.
require(
amountToWithdraw != 0 && providedCollateral.sub(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
IERC20(vAssets.collateralAsset).uniTransfer(msg.sender, amountToWithdraw);
emit Withdraw(msg.sender, vAssets.collateralAsset, amountToWithdraw);
} else {
// Logic used when called by Fliquidator
_withdraw(uint256(_withdrawAmount), address(activeProvider));
IERC20(vAssets.collateralAsset).uniTransfer(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();
uint256 providedCollateral =
IFujiERC1155(fujiERC1155).balanceOf(msg.sender, vAssets.collateralID);
// Get Required Collateral with Factors to maintain debt position healthy
uint256 neededCollateral =
getNeededCollateralFor(
_borrowAmount.add(IFujiERC1155(fujiERC1155).balanceOf(msg.sender, vAssets.borrowID)),
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
);
// Debt Management
IFujiERC1155(fujiERC1155).mint(msg.sender, vAssets.borrowID, _borrowAmount, "");
// Delegate Call Borrow to current provider
_borrow(_borrowAmount, address(activeProvider));
// Transer Assets to User
IERC20(vAssets.borrowAsset).uniTransfer(msg.sender, _borrowAmount);
emit Borrow(msg.sender, vAssets.borrowAsset, _borrowAmount);
}
/**
* @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 payback(int256 _repayAmount) public payable override {
// If call from Normal User do typical, otherwise Fliquidator
if (msg.sender != _fujiAdmin.getFliquidator()) {
updateF1155Balances();
uint256 userDebtBalance = IFujiERC1155(fujiERC1155).balanceOf(msg.sender, vAssets.borrowID);
// Check User Debt is greater than Zero and amount is not Zero
require(_repayAmount != 0 && userDebtBalance > 0, Errors.VL_NO_DEBT_TO_PAYBACK);
// TODO: Get => corresponding amount of BaseProtocol Debt and FujiDebt
// If passed argument amount is negative do MAX
uint256 amountToPayback = _repayAmount < 0 ? userDebtBalance : uint256(_repayAmount);
// Check User Allowance
require(
IERC20(vAssets.borrowAsset).allowance(msg.sender, address(this)) >= amountToPayback,
Errors.VL_MISSING_ERC20_ALLOWANCE
);
// Transfer Asset from User to Vault
IERC20(vAssets.borrowAsset).transferFrom(msg.sender, address(this), amountToPayback);
// Delegate Call Payback to current provider
_payback(amountToPayback, address(activeProvider));
//TODO: Transfer corresponding Debt Amount to Fuji Treasury
// Debt Management
IFujiERC1155(fujiERC1155).burn(msg.sender, vAssets.borrowID, amountToPayback);
emit Payback(msg.sender, vAssets.borrowAsset, userDebtBalance);
} else {
// Logic used when called by Fliquidator
_payback(uint256(_repayAmount), address(activeProvider));
}
}
/**
* @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 override onlyFlash whenNotPaused {
// Compute Ratio of transfer before payback
uint256 ratio =
(_flashLoanAmount).mul(1e18).div(
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).mul(ratio).div(1e18);
_withdraw(collateraltoMove, activeProvider);
// Deposit to the new provider
_deposit(collateraltoMove, _newProvider);
// Borrow from the new provider, borrowBalance + premium
_borrow(_flashLoanAmount.add(_fee), _newProvider);
// return borrowed amount to Flasher
IERC20(vAssets.borrowAsset).uniTransfer(msg.sender, _flashLoanAmount.add(_fee));
emit Switch(address(this), activeProvider, _newProvider, _flashLoanAmount, collateraltoMove);
}
//Setter, change state functions
/**
* @dev Sets the fujiAdmin Address
* @param _newFujiAdmin: FujiAdmin Contract Address
*/
function setFujiAdmin(address _newFujiAdmin) external onlyOwner {
_fujiAdmin = IFujiAdmin(_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 {
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
*/
function setFujiERC1155(address _fujiERC1155) external isAuthorized {
fujiERC1155 = _fujiERC1155;
vAssets.collateralID = IFujiERC1155(_fujiERC1155).addInitializeAsset(
IFujiERC1155.AssetType.collateralToken,
address(this)
);
vAssets.borrowID = IFujiERC1155(_fujiERC1155).addInitializeAsset(
IFujiERC1155.AssetType.debtToken,
address(this)
);
}
/**
* @dev Set Factors "a" and "b" for a Struct Factor
* For safetyF; Sets Safety Factor of Vault, should be > 1, a/b
* For collatF; Sets Collateral Factor of Vault, should be > 1, a/b
* @param _newFactorA: Nominator
* @param _newFactorB: Denominator
* @param _isSafety: safetyF or collatF
*/
function setFactor(
uint64 _newFactorA,
uint64 _newFactorB,
bool _isSafety
) external isAuthorized {
if (_isSafety) {
safetyF.a = _newFactorA;
safetyF.b = _newFactorB;
} else {
collatF.a = _newFactorA;
collatF.b = _newFactorB;
}
}
/**
* @dev Sets the Oracle address (Must Comply with AggregatorV3Interface)
* @param _oracle: new Oracle address
*/
function setOracle(address _oracle) external isAuthorized {
oracle = AggregatorV3Interface(_oracle);
}
/**
* @dev Set providers to the Vault
* @param _providers: new providers' addresses
*/
function setProviders(address[] calldata _providers) external isAuthorized {
providers = _providers;
}
/**
* @dev External Function to call updateState in F1155
*/
function updateF1155Balances() public override {
uint256 borrowBals;
uint256 depositBals;
// take into account all balances across providers
uint256 length = providers.length;
for (uint256 i = 0; i < length; i++) {
borrowBals = borrowBals.add(IProvider(providers[i]).getBorrowBalance(vAssets.borrowAsset));
}
for (uint256 i = 0; i < length; i++) {
depositBals = depositBals.add(
IProvider(providers[i]).getDepositBalance(vAssets.collateralAsset)
);
}
IFujiERC1155(fujiERC1155).updateState(vAssets.borrowID, borrowBals);
IFujiERC1155(fujiERC1155).updateState(vAssets.collateralID, depositBals);
}
//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
* @param _flash: Flash or classic type of liquidation, bonus differs
*/
function getLiquidationBonusFor(uint256 _amount, bool _flash)
external
view
override
returns (uint256)
{
if (_flash) {
// Bonus Factors for Flash Liquidation
(uint64 a, uint64 b) = _fujiAdmin.getBonusFlashL();
return _amount.mul(a).div(b);
} else {
//Bonus Factors for Normal Liquidation
(uint64 a, uint64 b) = _fujiAdmin.getBonusLiq();
return _amount.mul(a).div(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 price of USDC in ETH
(, int256 latestPrice, , , ) = oracle.latestRoundData();
uint256 minimumReq = (_amount.mul(1e12).mul(uint256(latestPrice))).div(_BASE);
if (_withFactors) {
return minimumReq.mul(collatF.a).mul(safetyF.a).div(collatF.b).div(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 Harvests the Rewards from baseLayer Protocols
* @param _farmProtocolNum: number per VaultHarvester Contract for specific farm
*/
function harvestRewards(uint256 _farmProtocolNum) external onlyOwner {
address tokenReturned =
IVaultHarvester(_fujiAdmin.getVaultHarvester()).collectRewards(_farmProtocolNum);
uint256 tokenBal = IERC20(tokenReturned).balanceOf(address(this));
require(tokenReturned != address(0) && tokenBal > 0, Errors.VL_HARVESTING_FAILED);
IERC20(tokenReturned).uniTransfer(payable(_fujiAdmin.getTreasury()), tokenBal);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.12;
pragma experimental ABIEncoderV2;
interface IVault {
// Events
// Log Users Deposit
event Deposit(address indexed userAddrs, address indexed asset, uint256 amount);
// Log Users withdraw
event Withdraw(address indexed userAddrs, address indexed asset, uint256 amount);
// Log Users borrow
event Borrow(address indexed userAddrs, address indexed asset, uint256 amount);
// Log Users debt repay
event Payback(address indexed userAddrs, address indexed asset, uint256 amount);
// Log New active provider
event SetActiveProvider(address providerAddr);
// Log Switch providers
event Switch(
address vault,
address fromProviderAddrs,
address toProviderAddr,
uint256 debtamount,
uint256 collattamount
);
// Core Vault Functions
function deposit(uint256 _collateralAmount) external payable;
function withdraw(int256 _withdrawAmount) external;
function borrow(uint256 _borrowAmount) external;
function payback(int256 _repayAmount) external payable;
function executeSwitch(
address _newProvider,
uint256 _flashLoanDebt,
uint256 _fee
) external;
//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 getNeededCollateralFor(uint256 _amount, bool _withFactors)
external
view
returns (uint256);
function getLiquidationBonusFor(uint256 _amount, bool _flash) 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;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.12;
import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { Pausable } from "@openzeppelin/contracts/utils/Pausable.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { UniERC20 } from "../Libraries/LibUniERC20.sol";
contract VaultControl is Ownable, Pausable {
using SafeMath for uint256;
using UniERC20 for IERC20;
//Asset Struct
struct VaultAssets {
address collateralAsset;
address borrowAsset;
uint64 collateralID;
uint64 borrowID;
}
//Vault Struct for Managed Assets
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 {
_pause();
}
}
contract VaultBase is VaultControl {
// 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)
internal
whenNotPaused
returns (bytes memory response)
{
/* solhint-disable */
assembly {
let succeeded := delegatecall(sub(gas(), 5000), _target, add(_data, 0x20), mload(_data), 0, 0)
let size := returndatasize()
response := mload(0x40)
mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))
mstore(response, size)
returndatacopy(add(response, 0x20), 0, size)
switch iszero(succeeded)
case 1 {
// throw if delegatecall failed
revert(add(response, 0x20), size)
}
}
/* solhint-disable */
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.12 <0.8.0;
interface IFujiAdmin {
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 getaWhiteList() external view returns (address);
function getVaultHarvester() external view returns (address);
function getBonusFlashL() external view returns (uint64, uint64);
function getBonusLiq() external view returns (uint64, uint64);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @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 ReentrancyGuard {
// 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;
constructor () internal {
_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 make 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;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.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.6.0 <0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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 `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, 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
pragma solidity >=0.6.12;
pragma experimental ABIEncoderV2;
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,
bytes memory _data
) 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.4.25 <0.7.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.6.12 <0.8.0;
interface IAlphaWhiteList {
function whiteListRoutine(
address _usrAddrs,
uint64 _assetId,
uint256 _amount,
address _erc1155
) external returns(bool);
}// SPDX-License-Identifier: agpl-3.0
pragma solidity <0.8.0;
/**
* @title Errors library
* @author Fuji
* @notice Defines the error messages emitted by the different contracts of the Aave protocol
* @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 MATH_DIVISION_BY_ZERO = "201";
string public constant MATH_ADDITION_OVERFLOW = "202";
string public constant MATH_MULTIPLICATION_OVERFLOW = "203";
string public constant RF_NO_GREENLIGHT = "300"; // Conditions for refinancing are not met, greenLight, deltaAPRThreshold, deltatimestampThreshold
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_CHECK_RATES_FALSE = "302"; //Check Rates routine returned False
string public constant VLT_CALLER_MUST_BE_VAULT = "401"; // The caller of this function must be a vault
string public constant SP_ALPHA_WHITELIST = "901"; // One ETH cap value for Alpha Version < 1 ETH
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../utils/Context.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 Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), 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 {
emit OwnershipTransferred(_owner, address(0));
_owner = 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");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./Context.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 Pausable is Context {
/**
* @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.
*/
constructor () internal {
_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());
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
library UniERC20 {
using SafeERC20 for IERC20;
IERC20 private constant _ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
IERC20 private constant _ZERO_ADDRESS = IERC20(0);
function isETH(IERC20 token) internal pure returns (bool) {
return (token == _ZERO_ADDRESS || token == _ETH_ADDRESS);
}
function uniBalanceOf(IERC20 token, address account) internal view returns (uint256) {
if (isETH(token)) {
return account.balance;
} else {
return token.balanceOf(account);
}
}
function uniTransfer(
IERC20 token,
address payable to,
uint256 amount
) internal {
if (amount > 0) {
if (isETH(token)) {
to.transfer(amount);
} else {
token.safeTransfer(to, amount);
}
}
}
function uniApprove(
IERC20 token,
address to,
uint256 amount
) internal {
require(!isETH(token), "Approve called on ETH");
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.6.0 <0.8.0;
/*
* @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 GSN 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 Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 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(IERC20 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'
// solhint-disable-next-line max-line-length
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(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_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(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @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
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 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");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(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");
// solhint-disable-next-line avoid-low-level-calls
(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");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}{
"optimizer": {
"enabled": true,
"runs": 1000
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":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":"providerAddr","type":"address"}],"name":"SetActiveProvider","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vault","type":"address"},{"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":"activeProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"nonpayable","type":"function"},{"inputs":[],"name":"fujiERC1155","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_flash","type":"bool"}],"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"}],"name":"harvestRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract AggregatorV3Interface","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":"uint256","name":"","type":"uint256"}],"name":"providers","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"bool","name":"_isSafety","type":"bool"}],"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":"_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":[],"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"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040523480156200001157600080fd5b5060006200001e62000113565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506000805460ff60a01b191690556001600481905580546001600160a01b031990811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee179091556002805490911673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481790556005805468140000000000000000600160401b600160801b03196001600160401b031992831660151781169190911790925560068054683f0000000000000000921660501790921617905562000117565b3390565b6138c780620001276000396000f3fe6080604052600436106102025760003560e01c80638456cb591161011d578063acb2d410116100b0578063c91c86031161007f578063d8df4ce711610064578063d8df4ce71461054c578063edc922a914610571578063f2fde38b1461059357610209565b8063c91c86031461050c578063cf4f44581461052c57610209565b8063acb2d410146104b1578063b6b55f25146104c6578063b75061bb146104d9578063c5ebeaec146104ec57610209565b8063956501bb116100ec578063956501bb1461043c57806397f75dd91461045c578063a0add93414610471578063a74159761461049157610209565b80638456cb591461026f5780638da5cb5b146103e757806390d7bfae146103fc57806391c154321461041c57610209565b80635c975abb116101955780637adbf973116101645780637adbf9731461037f5780637dc0d1d01461039f5780637e62eab8146103b45780637ec09f9d146103d457610209565b80635c975abb1461031357806367ac280a14610335578063715018a61461034a57806371e114301461035f57610209565b80634d73e9ba116101d15780634d73e9ba1461028457806350f3fc81146102b15780635564f53d146102de57806357126d0d146102f357610209565b806319e6e4151461020e5780631b98f6ac146102235780631c1fc2cc146102435780633f4ba83a1461026f57610209565b3661020957005b600080fd5b61022161021c366004613138565b6105b3565b005b34801561022f57600080fd5b5061022161023e3660046130ad565b6109f2565b34801561024f57600080fd5b50610258610afb565b604051610266929190613811565b60405180910390f35b34801561027b57600080fd5b50610221610b1b565b34801561029057600080fd5b506102a461029f366004613041565b610b64565b60405161026691906137ee565b3480156102bd57600080fd5b506102d16102cc366004613138565b610bed565b60405161026691906132b9565b3480156102ea57600080fd5b50610258610c14565b3480156102ff57600080fd5b5061022161030e366004613138565b610c34565b34801561031f57600080fd5b50610328610f1d565b6040516102669190613497565b34801561034157600080fd5b50610221610f2d565b34801561035657600080fd5b50610221611197565b34801561036b57600080fd5b5061022161037a366004613041565b611220565b34801561038b57600080fd5b5061022161039a366004613041565b61136e565b3480156103ab57600080fd5b506102d1611488565b3480156103c057600080fd5b506102216103cf366004613138565b611497565b6102216103e2366004613150565b6118b5565b3480156103f357600080fd5b506102d16118cb565b34801561040857600080fd5b506102a4610417366004613189565b6118da565b34801561042857600080fd5b50610221610437366004613041565b6119f7565b34801561044857600080fd5b506102a4610457366004613041565b611a58565b34801561046857600080fd5b506102d1611a8b565b34801561047d57600080fd5b5061022161048c366004613041565b611a9a565b34801561049d57600080fd5b506102216104ac366004613202565b611d0d565b3480156104bd57600080fd5b506102d1611e9f565b6102216104d4366004613138565b611eae565b6102216104e7366004613150565b61217e565b3480156104f857600080fd5b50610221610507366004613138565b61218c565b34801561051857600080fd5b506102a4610527366004613189565b6123f3565b34801561053857600080fd5b50610221610547366004613079565b61251e565b34801561055857600080fd5b50610561612812565b60405161026694939291906133fc565b34801561057d57600080fd5b50610586612842565b604051610266919061344a565b34801561059f57600080fd5b506102216105ae366004613041565b6128a4565b600960009054906101000a90046001600160a01b03166001600160a01b031663b8491a846040518163ffffffff1660e01b815260040160206040518083038186803b15801561060157600080fd5b505afa158015610615573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610639919061305d565b6001600160a01b0316336001600160a01b0316146109d857610659610f2d565b600a54600354604051627eeac760e11b81526000926001600160a01b03169162fdd58e9161069891339167ffffffffffffffff9091169060040161333f565b60206040518083038186803b1580156106b057600080fd5b505afa1580156106c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e89190613171565b905081158015906106f95750600081115b6040518060400160405280600381526020017f3130360000000000000000000000000000000000000000000000000000000000815250906107565760405162461bcd60e51b815260040161074d91906134c8565b60405180910390fd5b5060008083126107665782610768565b815b6002546040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815291925082916001600160a01b039091169063dd62ed3e906107b890339030906004016132cd565b60206040518083038186803b1580156107d057600080fd5b505afa1580156107e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108089190613171565b10156040518060400160405280600381526020017f31303700000000000000000000000000000000000000000000000000000000008152509061085e5760405162461bcd60e51b815260040161074d91906134c8565b506002546040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116906323b872dd906108ac903390309086906004016132e7565b602060405180830381600087803b1580156108c657600080fd5b505af11580156108da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fe919061311c565b506008546109169082906001600160a01b0316612964565b600a54600354604051637a94c56560e11b81526001600160a01b039092169163f5298aca9161095691339167ffffffffffffffff16908690600401613362565b600060405180830381600087803b15801561097057600080fd5b505af1158015610984573d6000803e3d6000fd5b50506002546040516001600160a01b0390911692503391507ffc2d2b4b3ad857c1c0893799f86b421efff822709b26de93df5709671f4841ca906109c99086906137ee565b60405180910390a350506109ef565b6008546109ef9082906001600160a01b0316612964565b50565b6109fa6118cb565b6001600160a01b0316336001600160a01b03161480610aaf5750600960009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a6257600080fd5b505afa158015610a76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9a919061305d565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b81525090610ae95760405162461bcd60e51b815260040161074d91906134c8565b50610af660078383612fa5565b505050565b60065467ffffffffffffffff808216916801000000000000000090041682565b610b236129dc565b6001600160a01b0316610b346118cb565b6001600160a01b031614610b5a5760405162461bcd60e51b815260040161074d906136ee565b610b626129e0565b565b600254604051637d6af07960e01b81526000916001600160a01b0380851692637d6af07992610b979216906004016132b9565b60206040518083038186803b158015610baf57600080fd5b505afa158015610bc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be79190613171565b92915050565b60078181548110610bfa57fe5b6000918252602090912001546001600160a01b0316905081565b60055467ffffffffffffffff808216916801000000000000000090041682565b610c3c6129dc565b6001600160a01b0316610c4d6118cb565b6001600160a01b031614610c735760405162461bcd60e51b815260040161074d906136ee565b600954604080517f68f1ecc300000000000000000000000000000000000000000000000000000000815290516000926001600160a01b0316916368f1ecc3916004808301926020929190829003018186803b158015610cd157600080fd5b505afa158015610ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d09919061305d565b6001600160a01b031663b18486d7836040518263ffffffff1660e01b8152600401610d3491906137ee565b602060405180830381600087803b158015610d4e57600080fd5b505af1158015610d62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d86919061305d565b90506000816001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610db691906132b9565b60206040518083038186803b158015610dce57600080fd5b505afa158015610de2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e069190613171565b90506001600160a01b03821615801590610e205750600081115b6040518060400160405280600381526020017f313236000000000000000000000000000000000000000000000000000000000081525090610e745760405162461bcd60e51b815260040161074d91906134c8565b50600954604080517f3b19e84a0000000000000000000000000000000000000000000000000000000081529051610af6926001600160a01b031691633b19e84a916004808301926020929190829003018186803b158015610ed457600080fd5b505afa158015610ee8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0c919061305d565b6001600160a01b0384169083612a73565b600054600160a01b900460ff1690565b6007546000908190815b81811015610fed57610fe360078281548110610f4f57fe5b600091825260209091200154600254604051637d6af07960e01b81526001600160a01b0392831692637d6af07992610f8c929116906004016132b9565b60206040518083038186803b158015610fa457600080fd5b505afa158015610fb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdc9190613171565b8590612ad7565b9350600101610f37565b5060005b818110156110a75761109d6007828154811061100957fe5b600091825260209091200154600154604051631da0b5cf60e31b81526001600160a01b039283169263ed05ae7892611046929116906004016132b9565b60206040518083038186803b15801561105e57600080fd5b505afa158015611072573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110969190613171565b8490612ad7565b9250600101610ff1565b50600a54600354604051635eb62f6360e01b81526001600160a01b0390921691635eb62f63916110e89167ffffffffffffffff9091169087906004016137f7565b600060405180830381600087803b15801561110257600080fd5b505af1158015611116573d6000803e3d6000fd5b5050600a54600254604051635eb62f6360e01b81526001600160a01b039092169350635eb62f63925061116091600160a01b90910467ffffffffffffffff169086906004016137f7565b600060405180830381600087803b15801561117a57600080fd5b505af115801561118e573d6000803e3d6000fd5b50505050505050565b61119f6129dc565b6001600160a01b03166111b06118cb565b6001600160a01b0316146111d65760405162461bcd60e51b815260040161074d906136ee565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6112286118cb565b6001600160a01b0316336001600160a01b031614806112dd5750600960009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561129057600080fd5b505afa1580156112a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c8919061305d565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b815250906113175760405162461bcd60e51b815260040161074d91906134c8565b50600880546001600160a01b0319166001600160a01b0383161790556040517f623e52a82ff2bab02a51be01f76b0b3178bbafcbe15c455b7ca4c9615b8da598906113639083906132b9565b60405180910390a150565b6113766118cb565b6001600160a01b0316336001600160a01b0316148061142b5750600960009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156113de57600080fd5b505afa1580156113f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611416919061305d565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b815250906114655760405162461bcd60e51b815260040161074d91906134c8565b50600b80546001600160a01b0319166001600160a01b0392909216919091179055565b600b546001600160a01b031681565b600260045414156114ba5760405162461bcd60e51b815260040161074d906137b7565b60026004908155600954604080517fb8491a8400000000000000000000000000000000000000000000000000000000815290516001600160a01b039092169263b8491a84928282019260209290829003018186803b15801561151b57600080fd5b505afa15801561152f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611553919061305d565b6001600160a01b0316336001600160a01b03161461187f57611573610f2d565b600a54600254604051627eeac760e11b81526000926001600160a01b03169162fdd58e916115b8913391600160a01b90910467ffffffffffffffff169060040161333f565b60206040518083038186803b1580156115d057600080fd5b505afa1580156115e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116089190613171565b9050600081116040518060400160405280600381526020017f3131320000000000000000000000000000000000000000000000000000000000815250906116625760405162461bcd60e51b815260040161074d91906134c8565b50600a54600354604051627eeac760e11b81526000926116fd926001600160a01b039091169162fdd58e916116a691339167ffffffffffffffff169060040161333f565b60206040518083038186803b1580156116be57600080fd5b505afa1580156116d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f69190613171565b60016118da565b9050600080841261170e5783611718565b6117188383612b03565b9050801580159061173257508161172f8483612b03565b10155b6040518060400160405280600381526020017f3130340000000000000000000000000000000000000000000000000000000000815250906117865760405162461bcd60e51b815260040161074d91906134c8565b50600a54600254604051637a94c56560e11b81526001600160a01b039092169163f5298aca916117ce913391600160a01b900467ffffffffffffffff16908690600401613362565b600060405180830381600087803b1580156117e857600080fd5b505af11580156117fc573d6000803e3d6000fd5b505060085461181792508391506001600160a01b0316612b2b565b60015461182e906001600160a01b03163383612a73565b6001546040516001600160a01b039091169033907f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb9061186f9085906137ee565b60405180910390a35050506118ad565b6008546118969082906001600160a01b0316612b2b565b6001546118ad906001600160a01b03163383612a73565b506001600455565b6118be826105b3565b6118c781611497565b5050565b6000546001600160a01b031690565b600080600b60009054906101000a90046001600160a01b03166001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561192b57600080fd5b505afa15801561193f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611963919061324c565b505050915050600061199f670de0b6b3a76400006119998461199364e8d4a510008a612b9d90919063ffffffff16565b90612b9d565b90612bd7565b905083156119ee576005546006546119e59167ffffffffffffffff6801000000000000000080830482169361199993918104831692849281169161199391899116612b9d565b92505050610be7565b9150610be79050565b6119ff6129dc565b6001600160a01b0316611a106118cb565b6001600160a01b031614611a365760405162461bcd60e51b815260040161074d906136ee565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b600154604051631da0b5cf60e31b81526000916001600160a01b038085169263ed05ae7892610b979216906004016132b9565b6008546001600160a01b031681565b611aa26118cb565b6001600160a01b0316336001600160a01b03161480611b575750600960009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b158015611b0a57600080fd5b505afa158015611b1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b42919061305d565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b81525090611b915760405162461bcd60e51b815260040161074d91906134c8565b50600a80546001600160a01b0319166001600160a01b0383169081179091556040516330e2d1ed60e01b81526330e2d1ed90611bd49060009030906004016134a2565b602060405180830381600087803b158015611bee57600080fd5b505af1158015611c02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2691906131b8565b6002805467ffffffffffffffff92909216600160a01b027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff9092169190911790556040516330e2d1ed60e01b81526001600160a01b038216906330e2d1ed90611c969060019030906004016134a2565b602060405180830381600087803b158015611cb057600080fd5b505af1158015611cc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ce891906131b8565b6003805467ffffffffffffffff191667ffffffffffffffff9290921691909117905550565b611d156118cb565b6001600160a01b0316336001600160a01b03161480611dca5750600960009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b158015611d7d57600080fd5b505afa158015611d91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db5919061305d565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b81525090611e045760405162461bcd60e51b815260040161074d91906134c8565b508015611e55576005805467ffffffffffffffff84811668010000000000000000026fffffffffffffffff00000000000000001991871667ffffffffffffffff199093169290921716179055610af6565b6006805467ffffffffffffffff84811668010000000000000000026fffffffffffffffff00000000000000001991871667ffffffffffffffff199093169290921716179055505050565b600a546001600160a01b031681565b8034148015611ebc57508015155b6040518060400160405280600381526020017f313033000000000000000000000000000000000000000000000000000000000081525090611f105760405162461bcd60e51b815260040161074d91906134c8565b50600960009054906101000a90046001600160a01b03166001600160a01b031663ee957e8b6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f5f57600080fd5b505afa158015611f73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f97919061305d565b600254600a546040517f67791c6a0000000000000000000000000000000000000000000000000000000081526001600160a01b03938416936367791c6a93611ffb933393600160a01b90920467ffffffffffffffff1692889291169060040161338d565b602060405180830381600087803b15801561201557600080fd5b505af1158015612029573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061204d919061311c565b6040518060400160405280600381526020017f3930310000000000000000000000000000000000000000000000000000000000815250906120a15760405162461bcd60e51b815260040161074d91906134c8565b506008546120b99082906001600160a01b0316612c09565b600a5460025460405163731133e960e01b81526001600160a01b039092169163731133e991612100913391600160a01b900467ffffffffffffffff169086906004016133c2565b600060405180830381600087803b15801561211a57600080fd5b505af115801561212e573d6000803e3d6000fd5b50506001546040516001600160a01b0390911692503391507f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62906121739085906137ee565b60405180910390a350565b61218782611eae565b6118c7815b600260045414156121af5760405162461bcd60e51b815260040161074d906137b7565b60026004556121bc610f2d565b600a54600254604051627eeac760e11b81526000926001600160a01b03169162fdd58e91612201913391600160a01b90910467ffffffffffffffff169060040161333f565b60206040518083038186803b15801561221957600080fd5b505afa15801561222d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122519190613171565b600a54600354604051627eeac760e11b815292935060009261229b926116f6926001600160a01b039091169162fdd58e91610f8c91339167ffffffffffffffff169060040161333f565b905082158015906122ab57508082115b6040518060400160405280600381526020017f3130350000000000000000000000000000000000000000000000000000000000815250906122ff5760405162461bcd60e51b815260040161074d91906134c8565b50600a5460035460405163731133e960e01b81526001600160a01b039092169163731133e99161234091339167ffffffffffffffff169088906004016133c2565b600060405180830381600087803b15801561235a57600080fd5b505af115801561236e573d6000803e3d6000fd5b505060085461238992508591506001600160a01b0316612c7b565b6002546123a0906001600160a01b03163385612a73565b6002546040516001600160a01b039091169033907f312a5e5e1079f5dda4e95dbbd0b908b291fd5b992ef22073643ab691572c5b52906123e19087906137ee565b60405180910390a35050600160045550565b600081156124c057600954604080517fe6ca33d8000000000000000000000000000000000000000000000000000000008152815160009384936001600160a01b039091169263e6ca33d89260048083019392829003018186803b15801561245957600080fd5b505afa15801561246d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061249191906131d4565b915091506119e58167ffffffffffffffff166119998467ffffffffffffffff1688612b9d90919063ffffffff16565b600954604080517fcfbfa328000000000000000000000000000000000000000000000000000000008152815160009384936001600160a01b039091169263cfbfa3289260048083019392829003018186803b15801561245957600080fd5b600960009054906101000a90046001600160a01b03166001600160a01b0316637fabc90b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561256c57600080fd5b505afa158015612580573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125a4919061305d565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016231313160e81b815250906125f25760405162461bcd60e51b815260040161074d91906134c8565b506125fb610f1d565b156126185760405162461bcd60e51b815260040161074d9061365a565b600854600254604051637d6af07960e01b81526000926126b4926001600160a01b0391821692637d6af079926126529216906004016132b9565b60206040518083038186803b15801561266a57600080fd5b505afa15801561267e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126a29190613171565b61199985670de0b6b3a7640000612b9d565b6008549091506126ce9084906001600160a01b0316612964565b600854600154604051631da0b5cf60e31b815260009261276892670de0b6b3a7640000926119999287926001600160a01b039182169263ed05ae78926127189216906004016132b9565b60206040518083038186803b15801561273057600080fd5b505afa158015612744573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119939190613171565b6008549091506127829082906001600160a01b0316612b2b565b61278c8186612c09565b61279f6127998585612ad7565b86612c7b565b6127c0336127ad8686612ad7565b6002546001600160a01b03169190612a73565b6008546040517f6e5fd9ca16b4a986eb739b97b83a96e3a1cc770b5db94d98813d02d06ffdf783916128039130916001600160a01b03169089908990879061330b565b60405180910390a15050505050565b6001546002546003546001600160a01b039283169282169167ffffffffffffffff600160a01b9091048116911684565b6060600780548060200260200160405190810160405280929190818152602001828054801561289a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161287c575b5050505050905090565b6128ac6129dc565b6001600160a01b03166128bd6118cb565b6001600160a01b0316146128e35760405162461bcd60e51b815260040161074d906136ee565b6001600160a01b0381166129095760405162461bcd60e51b815260040161074d906134fb565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600254604051606091612987916001600160a01b03909116908590602401613431565b60408051601f198184030181529190526020810180516001600160e01b03167f35ed8ab80000000000000000000000000000000000000000000000000000000017905290506129d68282612ce9565b50505050565b3390565b6129e8610f1d565b15612a055760405162461bcd60e51b815260040161074d9061365a565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612a5c6129dc565b604051612a6991906132b9565b60405180910390a1565b8015610af657612a8283612d60565b15612ac3576040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015612abd573d6000803e3d6000fd5b50610af6565b610af66001600160a01b0384168383612d96565b600082820183811015612afc5760405162461bcd60e51b815260040161074d90613558565b9392505050565b600082821115612b255760405162461bcd60e51b815260040161074d9061358f565b50900390565b600154604051606091612b4e916001600160a01b03909116908590602401613431565b60408051601f198184030181529190526020810180516001600160e01b03167ff3fef3a30000000000000000000000000000000000000000000000000000000017905290506129d68282612ce9565b600082612bac57506000610be7565b82820282848281612bb957fe5b0414612afc5760405162461bcd60e51b815260040161074d90613691565b6000808211612bf85760405162461bcd60e51b815260040161074d90613623565b818381612c0157fe5b049392505050565b600154604051606091612c2c916001600160a01b03909116908590602401613431565b60408051601f198184030181529190526020810180516001600160e01b03167f47e7ef240000000000000000000000000000000000000000000000000000000017905290506129d68282612ce9565b600254604051606091612c9e916001600160a01b03909116908590602401613431565b60408051601f198184030181529190526020810180516001600160e01b03167f4b8a35290000000000000000000000000000000000000000000000000000000017905290506129d682825b6060612cf3610f1d565b15612d105760405162461bcd60e51b815260040161074d9061365a565b600080835160208501866113885a03f43d6040519250601f19601f6020830101168301604052808352806000602085013e811560018114612d5057612d57565b8160208501fd5b50505092915050565b60006001600160a01b0382161580610be75750506001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b610af68363a9059cbb60e01b8484604051602401612db5929190613431565b60408051601f198184030181529190526020810180516001600160e01b03167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526060612e54826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e8e9092919063ffffffff16565b805190915015610af65780806020019051810190612e72919061311c565b610af65760405162461bcd60e51b815260040161074d9061375a565b6060612e9d8484600085612ea5565b949350505050565b606082471015612ec75760405162461bcd60e51b815260040161074d906135c6565b612ed085612f66565b612eec5760405162461bcd60e51b815260040161074d90613723565b60006060866001600160a01b03168587604051612f09919061329d565b60006040518083038185875af1925050503d8060008114612f46576040519150601f19603f3d011682016040523d82523d6000602084013e612f4b565b606091505b5091509150612f5b828286612f6c565b979650505050505050565b3b151590565b60608315612f7b575081612afc565b825115612f8b5782518084602001fd5b8160405162461bcd60e51b815260040161074d91906134c8565b828054828255906000526020600020908101928215612ff8579160200282015b82811115612ff85781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190612fc5565b50613004929150613008565b5090565b5b808211156130045780546001600160a01b0319168155600101613009565b805169ffffffffffffffffffff81168114610be757600080fd5b600060208284031215613052578081fd5b8135612afc81613858565b60006020828403121561306e578081fd5b8151612afc81613858565b60008060006060848603121561308d578182fd5b833561309881613858565b95602085013595506040909401359392505050565b600080602083850312156130bf578182fd5b823567ffffffffffffffff808211156130d6578384fd5b818501915085601f8301126130e9578384fd5b8135818111156130f7578485fd5b866020808302850101111561310a578485fd5b60209290920196919550909350505050565b60006020828403121561312d578081fd5b8151612afc8161386d565b600060208284031215613149578081fd5b5035919050565b60008060408385031215613162578182fd5b50508035926020909101359150565b600060208284031215613182578081fd5b5051919050565b6000806040838503121561319b578182fd5b8235915060208301356131ad8161386d565b809150509250929050565b6000602082840312156131c9578081fd5b8151612afc8161387b565b600080604083850312156131e6578182fd5b82516131f18161387b565b60208401519092506131ad8161387b565b600080600060608486031215613216578081fd5b83356132218161387b565b925060208401356132318161387b565b915060408401356132418161386d565b809150509250925092565b600080600080600060a08688031215613263578283fd5b61326d8787613027565b94506020860151935060408601519250606086015191506132918760808801613027565b90509295509295909350565b600082516132af81846020870161382c565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03958616815293851660208501529190931660408301526060820192909252608081019190915260a00190565b6001600160a01b0392909216825267ffffffffffffffff16602082015260400190565b6001600160a01b0393909316835267ffffffffffffffff919091166020830152604082015260600190565b6001600160a01b03948516815267ffffffffffffffff9390931660208401526040830191909152909116606082015260800190565b6001600160a01b0393909316835267ffffffffffffffff919091166020830152604082015260806060820181905260009082015260a00190565b6001600160a01b03948516815292909316602083015267ffffffffffffffff9081166040830152909116606082015260800190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101561348b5783516001600160a01b031683529284019291840191600101613466565b50909695505050505050565b901515815260200190565b60408101600284106134b057fe5b9281526001600160a01b039190911660209091015290565b60006020825282518060208401526134e781604085016020870161382c565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60408201527f722063616c6c0000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b60208082526010908201527f5061757361626c653a2070617573656400000000000000000000000000000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60408201527f6f74207375636365656400000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b90815260200190565b67ffffffffffffffff929092168252602082015260400190565b67ffffffffffffffff92831681529116602082015260400190565b60005b8381101561384757818101518382015260200161382f565b838111156129d65750506000910152565b6001600160a01b03811681146109ef57600080fd5b80151581146109ef57600080fd5b67ffffffffffffffff811681146109ef57600080fdfea26469706673582212207e8687cc5e9712b94a8500cd0965317f54eaa858dfc18f75e61807a7e6e474f764736f6c634300060c0033
Deployed Bytecode
0x6080604052600436106102025760003560e01c80638456cb591161011d578063acb2d410116100b0578063c91c86031161007f578063d8df4ce711610064578063d8df4ce71461054c578063edc922a914610571578063f2fde38b1461059357610209565b8063c91c86031461050c578063cf4f44581461052c57610209565b8063acb2d410146104b1578063b6b55f25146104c6578063b75061bb146104d9578063c5ebeaec146104ec57610209565b8063956501bb116100ec578063956501bb1461043c57806397f75dd91461045c578063a0add93414610471578063a74159761461049157610209565b80638456cb591461026f5780638da5cb5b146103e757806390d7bfae146103fc57806391c154321461041c57610209565b80635c975abb116101955780637adbf973116101645780637adbf9731461037f5780637dc0d1d01461039f5780637e62eab8146103b45780637ec09f9d146103d457610209565b80635c975abb1461031357806367ac280a14610335578063715018a61461034a57806371e114301461035f57610209565b80634d73e9ba116101d15780634d73e9ba1461028457806350f3fc81146102b15780635564f53d146102de57806357126d0d146102f357610209565b806319e6e4151461020e5780631b98f6ac146102235780631c1fc2cc146102435780633f4ba83a1461026f57610209565b3661020957005b600080fd5b61022161021c366004613138565b6105b3565b005b34801561022f57600080fd5b5061022161023e3660046130ad565b6109f2565b34801561024f57600080fd5b50610258610afb565b604051610266929190613811565b60405180910390f35b34801561027b57600080fd5b50610221610b1b565b34801561029057600080fd5b506102a461029f366004613041565b610b64565b60405161026691906137ee565b3480156102bd57600080fd5b506102d16102cc366004613138565b610bed565b60405161026691906132b9565b3480156102ea57600080fd5b50610258610c14565b3480156102ff57600080fd5b5061022161030e366004613138565b610c34565b34801561031f57600080fd5b50610328610f1d565b6040516102669190613497565b34801561034157600080fd5b50610221610f2d565b34801561035657600080fd5b50610221611197565b34801561036b57600080fd5b5061022161037a366004613041565b611220565b34801561038b57600080fd5b5061022161039a366004613041565b61136e565b3480156103ab57600080fd5b506102d1611488565b3480156103c057600080fd5b506102216103cf366004613138565b611497565b6102216103e2366004613150565b6118b5565b3480156103f357600080fd5b506102d16118cb565b34801561040857600080fd5b506102a4610417366004613189565b6118da565b34801561042857600080fd5b50610221610437366004613041565b6119f7565b34801561044857600080fd5b506102a4610457366004613041565b611a58565b34801561046857600080fd5b506102d1611a8b565b34801561047d57600080fd5b5061022161048c366004613041565b611a9a565b34801561049d57600080fd5b506102216104ac366004613202565b611d0d565b3480156104bd57600080fd5b506102d1611e9f565b6102216104d4366004613138565b611eae565b6102216104e7366004613150565b61217e565b3480156104f857600080fd5b50610221610507366004613138565b61218c565b34801561051857600080fd5b506102a4610527366004613189565b6123f3565b34801561053857600080fd5b50610221610547366004613079565b61251e565b34801561055857600080fd5b50610561612812565b60405161026694939291906133fc565b34801561057d57600080fd5b50610586612842565b604051610266919061344a565b34801561059f57600080fd5b506102216105ae366004613041565b6128a4565b600960009054906101000a90046001600160a01b03166001600160a01b031663b8491a846040518163ffffffff1660e01b815260040160206040518083038186803b15801561060157600080fd5b505afa158015610615573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610639919061305d565b6001600160a01b0316336001600160a01b0316146109d857610659610f2d565b600a54600354604051627eeac760e11b81526000926001600160a01b03169162fdd58e9161069891339167ffffffffffffffff9091169060040161333f565b60206040518083038186803b1580156106b057600080fd5b505afa1580156106c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e89190613171565b905081158015906106f95750600081115b6040518060400160405280600381526020017f3130360000000000000000000000000000000000000000000000000000000000815250906107565760405162461bcd60e51b815260040161074d91906134c8565b60405180910390fd5b5060008083126107665782610768565b815b6002546040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815291925082916001600160a01b039091169063dd62ed3e906107b890339030906004016132cd565b60206040518083038186803b1580156107d057600080fd5b505afa1580156107e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108089190613171565b10156040518060400160405280600381526020017f31303700000000000000000000000000000000000000000000000000000000008152509061085e5760405162461bcd60e51b815260040161074d91906134c8565b506002546040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116906323b872dd906108ac903390309086906004016132e7565b602060405180830381600087803b1580156108c657600080fd5b505af11580156108da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fe919061311c565b506008546109169082906001600160a01b0316612964565b600a54600354604051637a94c56560e11b81526001600160a01b039092169163f5298aca9161095691339167ffffffffffffffff16908690600401613362565b600060405180830381600087803b15801561097057600080fd5b505af1158015610984573d6000803e3d6000fd5b50506002546040516001600160a01b0390911692503391507ffc2d2b4b3ad857c1c0893799f86b421efff822709b26de93df5709671f4841ca906109c99086906137ee565b60405180910390a350506109ef565b6008546109ef9082906001600160a01b0316612964565b50565b6109fa6118cb565b6001600160a01b0316336001600160a01b03161480610aaf5750600960009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a6257600080fd5b505afa158015610a76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9a919061305d565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b81525090610ae95760405162461bcd60e51b815260040161074d91906134c8565b50610af660078383612fa5565b505050565b60065467ffffffffffffffff808216916801000000000000000090041682565b610b236129dc565b6001600160a01b0316610b346118cb565b6001600160a01b031614610b5a5760405162461bcd60e51b815260040161074d906136ee565b610b626129e0565b565b600254604051637d6af07960e01b81526000916001600160a01b0380851692637d6af07992610b979216906004016132b9565b60206040518083038186803b158015610baf57600080fd5b505afa158015610bc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be79190613171565b92915050565b60078181548110610bfa57fe5b6000918252602090912001546001600160a01b0316905081565b60055467ffffffffffffffff808216916801000000000000000090041682565b610c3c6129dc565b6001600160a01b0316610c4d6118cb565b6001600160a01b031614610c735760405162461bcd60e51b815260040161074d906136ee565b600954604080517f68f1ecc300000000000000000000000000000000000000000000000000000000815290516000926001600160a01b0316916368f1ecc3916004808301926020929190829003018186803b158015610cd157600080fd5b505afa158015610ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d09919061305d565b6001600160a01b031663b18486d7836040518263ffffffff1660e01b8152600401610d3491906137ee565b602060405180830381600087803b158015610d4e57600080fd5b505af1158015610d62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d86919061305d565b90506000816001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610db691906132b9565b60206040518083038186803b158015610dce57600080fd5b505afa158015610de2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e069190613171565b90506001600160a01b03821615801590610e205750600081115b6040518060400160405280600381526020017f313236000000000000000000000000000000000000000000000000000000000081525090610e745760405162461bcd60e51b815260040161074d91906134c8565b50600954604080517f3b19e84a0000000000000000000000000000000000000000000000000000000081529051610af6926001600160a01b031691633b19e84a916004808301926020929190829003018186803b158015610ed457600080fd5b505afa158015610ee8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0c919061305d565b6001600160a01b0384169083612a73565b600054600160a01b900460ff1690565b6007546000908190815b81811015610fed57610fe360078281548110610f4f57fe5b600091825260209091200154600254604051637d6af07960e01b81526001600160a01b0392831692637d6af07992610f8c929116906004016132b9565b60206040518083038186803b158015610fa457600080fd5b505afa158015610fb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdc9190613171565b8590612ad7565b9350600101610f37565b5060005b818110156110a75761109d6007828154811061100957fe5b600091825260209091200154600154604051631da0b5cf60e31b81526001600160a01b039283169263ed05ae7892611046929116906004016132b9565b60206040518083038186803b15801561105e57600080fd5b505afa158015611072573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110969190613171565b8490612ad7565b9250600101610ff1565b50600a54600354604051635eb62f6360e01b81526001600160a01b0390921691635eb62f63916110e89167ffffffffffffffff9091169087906004016137f7565b600060405180830381600087803b15801561110257600080fd5b505af1158015611116573d6000803e3d6000fd5b5050600a54600254604051635eb62f6360e01b81526001600160a01b039092169350635eb62f63925061116091600160a01b90910467ffffffffffffffff169086906004016137f7565b600060405180830381600087803b15801561117a57600080fd5b505af115801561118e573d6000803e3d6000fd5b50505050505050565b61119f6129dc565b6001600160a01b03166111b06118cb565b6001600160a01b0316146111d65760405162461bcd60e51b815260040161074d906136ee565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6112286118cb565b6001600160a01b0316336001600160a01b031614806112dd5750600960009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561129057600080fd5b505afa1580156112a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c8919061305d565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b815250906113175760405162461bcd60e51b815260040161074d91906134c8565b50600880546001600160a01b0319166001600160a01b0383161790556040517f623e52a82ff2bab02a51be01f76b0b3178bbafcbe15c455b7ca4c9615b8da598906113639083906132b9565b60405180910390a150565b6113766118cb565b6001600160a01b0316336001600160a01b0316148061142b5750600960009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156113de57600080fd5b505afa1580156113f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611416919061305d565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b815250906114655760405162461bcd60e51b815260040161074d91906134c8565b50600b80546001600160a01b0319166001600160a01b0392909216919091179055565b600b546001600160a01b031681565b600260045414156114ba5760405162461bcd60e51b815260040161074d906137b7565b60026004908155600954604080517fb8491a8400000000000000000000000000000000000000000000000000000000815290516001600160a01b039092169263b8491a84928282019260209290829003018186803b15801561151b57600080fd5b505afa15801561152f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611553919061305d565b6001600160a01b0316336001600160a01b03161461187f57611573610f2d565b600a54600254604051627eeac760e11b81526000926001600160a01b03169162fdd58e916115b8913391600160a01b90910467ffffffffffffffff169060040161333f565b60206040518083038186803b1580156115d057600080fd5b505afa1580156115e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116089190613171565b9050600081116040518060400160405280600381526020017f3131320000000000000000000000000000000000000000000000000000000000815250906116625760405162461bcd60e51b815260040161074d91906134c8565b50600a54600354604051627eeac760e11b81526000926116fd926001600160a01b039091169162fdd58e916116a691339167ffffffffffffffff169060040161333f565b60206040518083038186803b1580156116be57600080fd5b505afa1580156116d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f69190613171565b60016118da565b9050600080841261170e5783611718565b6117188383612b03565b9050801580159061173257508161172f8483612b03565b10155b6040518060400160405280600381526020017f3130340000000000000000000000000000000000000000000000000000000000815250906117865760405162461bcd60e51b815260040161074d91906134c8565b50600a54600254604051637a94c56560e11b81526001600160a01b039092169163f5298aca916117ce913391600160a01b900467ffffffffffffffff16908690600401613362565b600060405180830381600087803b1580156117e857600080fd5b505af11580156117fc573d6000803e3d6000fd5b505060085461181792508391506001600160a01b0316612b2b565b60015461182e906001600160a01b03163383612a73565b6001546040516001600160a01b039091169033907f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb9061186f9085906137ee565b60405180910390a35050506118ad565b6008546118969082906001600160a01b0316612b2b565b6001546118ad906001600160a01b03163383612a73565b506001600455565b6118be826105b3565b6118c781611497565b5050565b6000546001600160a01b031690565b600080600b60009054906101000a90046001600160a01b03166001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561192b57600080fd5b505afa15801561193f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611963919061324c565b505050915050600061199f670de0b6b3a76400006119998461199364e8d4a510008a612b9d90919063ffffffff16565b90612b9d565b90612bd7565b905083156119ee576005546006546119e59167ffffffffffffffff6801000000000000000080830482169361199993918104831692849281169161199391899116612b9d565b92505050610be7565b9150610be79050565b6119ff6129dc565b6001600160a01b0316611a106118cb565b6001600160a01b031614611a365760405162461bcd60e51b815260040161074d906136ee565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b600154604051631da0b5cf60e31b81526000916001600160a01b038085169263ed05ae7892610b979216906004016132b9565b6008546001600160a01b031681565b611aa26118cb565b6001600160a01b0316336001600160a01b03161480611b575750600960009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b158015611b0a57600080fd5b505afa158015611b1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b42919061305d565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b81525090611b915760405162461bcd60e51b815260040161074d91906134c8565b50600a80546001600160a01b0319166001600160a01b0383169081179091556040516330e2d1ed60e01b81526330e2d1ed90611bd49060009030906004016134a2565b602060405180830381600087803b158015611bee57600080fd5b505af1158015611c02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2691906131b8565b6002805467ffffffffffffffff92909216600160a01b027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff9092169190911790556040516330e2d1ed60e01b81526001600160a01b038216906330e2d1ed90611c969060019030906004016134a2565b602060405180830381600087803b158015611cb057600080fd5b505af1158015611cc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ce891906131b8565b6003805467ffffffffffffffff191667ffffffffffffffff9290921691909117905550565b611d156118cb565b6001600160a01b0316336001600160a01b03161480611dca5750600960009054906101000a90046001600160a01b03166001600160a01b0316633018205f6040518163ffffffff1660e01b815260040160206040518083038186803b158015611d7d57600080fd5b505afa158015611d91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db5919061305d565b6001600160a01b0316336001600160a01b0316145b6040518060400160405280600381526020016231313160e81b81525090611e045760405162461bcd60e51b815260040161074d91906134c8565b508015611e55576005805467ffffffffffffffff84811668010000000000000000026fffffffffffffffff00000000000000001991871667ffffffffffffffff199093169290921716179055610af6565b6006805467ffffffffffffffff84811668010000000000000000026fffffffffffffffff00000000000000001991871667ffffffffffffffff199093169290921716179055505050565b600a546001600160a01b031681565b8034148015611ebc57508015155b6040518060400160405280600381526020017f313033000000000000000000000000000000000000000000000000000000000081525090611f105760405162461bcd60e51b815260040161074d91906134c8565b50600960009054906101000a90046001600160a01b03166001600160a01b031663ee957e8b6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f5f57600080fd5b505afa158015611f73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f97919061305d565b600254600a546040517f67791c6a0000000000000000000000000000000000000000000000000000000081526001600160a01b03938416936367791c6a93611ffb933393600160a01b90920467ffffffffffffffff1692889291169060040161338d565b602060405180830381600087803b15801561201557600080fd5b505af1158015612029573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061204d919061311c565b6040518060400160405280600381526020017f3930310000000000000000000000000000000000000000000000000000000000815250906120a15760405162461bcd60e51b815260040161074d91906134c8565b506008546120b99082906001600160a01b0316612c09565b600a5460025460405163731133e960e01b81526001600160a01b039092169163731133e991612100913391600160a01b900467ffffffffffffffff169086906004016133c2565b600060405180830381600087803b15801561211a57600080fd5b505af115801561212e573d6000803e3d6000fd5b50506001546040516001600160a01b0390911692503391507f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62906121739085906137ee565b60405180910390a350565b61218782611eae565b6118c7815b600260045414156121af5760405162461bcd60e51b815260040161074d906137b7565b60026004556121bc610f2d565b600a54600254604051627eeac760e11b81526000926001600160a01b03169162fdd58e91612201913391600160a01b90910467ffffffffffffffff169060040161333f565b60206040518083038186803b15801561221957600080fd5b505afa15801561222d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122519190613171565b600a54600354604051627eeac760e11b815292935060009261229b926116f6926001600160a01b039091169162fdd58e91610f8c91339167ffffffffffffffff169060040161333f565b905082158015906122ab57508082115b6040518060400160405280600381526020017f3130350000000000000000000000000000000000000000000000000000000000815250906122ff5760405162461bcd60e51b815260040161074d91906134c8565b50600a5460035460405163731133e960e01b81526001600160a01b039092169163731133e99161234091339167ffffffffffffffff169088906004016133c2565b600060405180830381600087803b15801561235a57600080fd5b505af115801561236e573d6000803e3d6000fd5b505060085461238992508591506001600160a01b0316612c7b565b6002546123a0906001600160a01b03163385612a73565b6002546040516001600160a01b039091169033907f312a5e5e1079f5dda4e95dbbd0b908b291fd5b992ef22073643ab691572c5b52906123e19087906137ee565b60405180910390a35050600160045550565b600081156124c057600954604080517fe6ca33d8000000000000000000000000000000000000000000000000000000008152815160009384936001600160a01b039091169263e6ca33d89260048083019392829003018186803b15801561245957600080fd5b505afa15801561246d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061249191906131d4565b915091506119e58167ffffffffffffffff166119998467ffffffffffffffff1688612b9d90919063ffffffff16565b600954604080517fcfbfa328000000000000000000000000000000000000000000000000000000008152815160009384936001600160a01b039091169263cfbfa3289260048083019392829003018186803b15801561245957600080fd5b600960009054906101000a90046001600160a01b03166001600160a01b0316637fabc90b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561256c57600080fd5b505afa158015612580573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125a4919061305d565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016231313160e81b815250906125f25760405162461bcd60e51b815260040161074d91906134c8565b506125fb610f1d565b156126185760405162461bcd60e51b815260040161074d9061365a565b600854600254604051637d6af07960e01b81526000926126b4926001600160a01b0391821692637d6af079926126529216906004016132b9565b60206040518083038186803b15801561266a57600080fd5b505afa15801561267e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126a29190613171565b61199985670de0b6b3a7640000612b9d565b6008549091506126ce9084906001600160a01b0316612964565b600854600154604051631da0b5cf60e31b815260009261276892670de0b6b3a7640000926119999287926001600160a01b039182169263ed05ae78926127189216906004016132b9565b60206040518083038186803b15801561273057600080fd5b505afa158015612744573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119939190613171565b6008549091506127829082906001600160a01b0316612b2b565b61278c8186612c09565b61279f6127998585612ad7565b86612c7b565b6127c0336127ad8686612ad7565b6002546001600160a01b03169190612a73565b6008546040517f6e5fd9ca16b4a986eb739b97b83a96e3a1cc770b5db94d98813d02d06ffdf783916128039130916001600160a01b03169089908990879061330b565b60405180910390a15050505050565b6001546002546003546001600160a01b039283169282169167ffffffffffffffff600160a01b9091048116911684565b6060600780548060200260200160405190810160405280929190818152602001828054801561289a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161287c575b5050505050905090565b6128ac6129dc565b6001600160a01b03166128bd6118cb565b6001600160a01b0316146128e35760405162461bcd60e51b815260040161074d906136ee565b6001600160a01b0381166129095760405162461bcd60e51b815260040161074d906134fb565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600254604051606091612987916001600160a01b03909116908590602401613431565b60408051601f198184030181529190526020810180516001600160e01b03167f35ed8ab80000000000000000000000000000000000000000000000000000000017905290506129d68282612ce9565b50505050565b3390565b6129e8610f1d565b15612a055760405162461bcd60e51b815260040161074d9061365a565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612a5c6129dc565b604051612a6991906132b9565b60405180910390a1565b8015610af657612a8283612d60565b15612ac3576040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015612abd573d6000803e3d6000fd5b50610af6565b610af66001600160a01b0384168383612d96565b600082820183811015612afc5760405162461bcd60e51b815260040161074d90613558565b9392505050565b600082821115612b255760405162461bcd60e51b815260040161074d9061358f565b50900390565b600154604051606091612b4e916001600160a01b03909116908590602401613431565b60408051601f198184030181529190526020810180516001600160e01b03167ff3fef3a30000000000000000000000000000000000000000000000000000000017905290506129d68282612ce9565b600082612bac57506000610be7565b82820282848281612bb957fe5b0414612afc5760405162461bcd60e51b815260040161074d90613691565b6000808211612bf85760405162461bcd60e51b815260040161074d90613623565b818381612c0157fe5b049392505050565b600154604051606091612c2c916001600160a01b03909116908590602401613431565b60408051601f198184030181529190526020810180516001600160e01b03167f47e7ef240000000000000000000000000000000000000000000000000000000017905290506129d68282612ce9565b600254604051606091612c9e916001600160a01b03909116908590602401613431565b60408051601f198184030181529190526020810180516001600160e01b03167f4b8a35290000000000000000000000000000000000000000000000000000000017905290506129d682825b6060612cf3610f1d565b15612d105760405162461bcd60e51b815260040161074d9061365a565b600080835160208501866113885a03f43d6040519250601f19601f6020830101168301604052808352806000602085013e811560018114612d5057612d57565b8160208501fd5b50505092915050565b60006001600160a01b0382161580610be75750506001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b610af68363a9059cbb60e01b8484604051602401612db5929190613431565b60408051601f198184030181529190526020810180516001600160e01b03167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526060612e54826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e8e9092919063ffffffff16565b805190915015610af65780806020019051810190612e72919061311c565b610af65760405162461bcd60e51b815260040161074d9061375a565b6060612e9d8484600085612ea5565b949350505050565b606082471015612ec75760405162461bcd60e51b815260040161074d906135c6565b612ed085612f66565b612eec5760405162461bcd60e51b815260040161074d90613723565b60006060866001600160a01b03168587604051612f09919061329d565b60006040518083038185875af1925050503d8060008114612f46576040519150601f19603f3d011682016040523d82523d6000602084013e612f4b565b606091505b5091509150612f5b828286612f6c565b979650505050505050565b3b151590565b60608315612f7b575081612afc565b825115612f8b5782518084602001fd5b8160405162461bcd60e51b815260040161074d91906134c8565b828054828255906000526020600020908101928215612ff8579160200282015b82811115612ff85781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190612fc5565b50613004929150613008565b5090565b5b808211156130045780546001600160a01b0319168155600101613009565b805169ffffffffffffffffffff81168114610be757600080fd5b600060208284031215613052578081fd5b8135612afc81613858565b60006020828403121561306e578081fd5b8151612afc81613858565b60008060006060848603121561308d578182fd5b833561309881613858565b95602085013595506040909401359392505050565b600080602083850312156130bf578182fd5b823567ffffffffffffffff808211156130d6578384fd5b818501915085601f8301126130e9578384fd5b8135818111156130f7578485fd5b866020808302850101111561310a578485fd5b60209290920196919550909350505050565b60006020828403121561312d578081fd5b8151612afc8161386d565b600060208284031215613149578081fd5b5035919050565b60008060408385031215613162578182fd5b50508035926020909101359150565b600060208284031215613182578081fd5b5051919050565b6000806040838503121561319b578182fd5b8235915060208301356131ad8161386d565b809150509250929050565b6000602082840312156131c9578081fd5b8151612afc8161387b565b600080604083850312156131e6578182fd5b82516131f18161387b565b60208401519092506131ad8161387b565b600080600060608486031215613216578081fd5b83356132218161387b565b925060208401356132318161387b565b915060408401356132418161386d565b809150509250925092565b600080600080600060a08688031215613263578283fd5b61326d8787613027565b94506020860151935060408601519250606086015191506132918760808801613027565b90509295509295909350565b600082516132af81846020870161382c565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03958616815293851660208501529190931660408301526060820192909252608081019190915260a00190565b6001600160a01b0392909216825267ffffffffffffffff16602082015260400190565b6001600160a01b0393909316835267ffffffffffffffff919091166020830152604082015260600190565b6001600160a01b03948516815267ffffffffffffffff9390931660208401526040830191909152909116606082015260800190565b6001600160a01b0393909316835267ffffffffffffffff919091166020830152604082015260806060820181905260009082015260a00190565b6001600160a01b03948516815292909316602083015267ffffffffffffffff9081166040830152909116606082015260800190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101561348b5783516001600160a01b031683529284019291840191600101613466565b50909695505050505050565b901515815260200190565b60408101600284106134b057fe5b9281526001600160a01b039190911660209091015290565b60006020825282518060208401526134e781604085016020870161382c565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60408201527f722063616c6c0000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b60208082526010908201527f5061757361626c653a2070617573656400000000000000000000000000000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60408201527f6f74207375636365656400000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b90815260200190565b67ffffffffffffffff929092168252602082015260400190565b67ffffffffffffffff92831681529116602082015260400190565b60005b8381101561384757818101518382015260200161382f565b838111156129d65750506000910152565b6001600160a01b03811681146109ef57600080fd5b80151581146109ef57600080fd5b67ffffffffffffffff811681146109ef57600080fdfea26469706673582212207e8687cc5e9712b94a8500cd0965317f54eaa858dfc18f75e61807a7e6e474f764736f6c634300060c0033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$1,872.20
Net Worth in ETH
0.958678
Token Allocations
USDC
97.12%
ETH
2.71%
CETH
0.12%
Others
0.05%
Multichain Portfolio | 34 Chains
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.