Source Code
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
DebtToken
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "./utils/ReentrancyGuard.sol";
import "./utils/TokenHolder.sol";
import "./access/Manageable.sol";
import "./storage/DebtTokenStorage.sol";
import "./lib/WadRayMath.sol";
error SyntheticDoesNotExist();
error SyntheticIsInactive();
error DebtTokenInactive();
error NameIsNull();
error SymbolIsNull();
error PoolIsNull();
error SyntheticIsNull();
error AllowanceNotSupported();
error ApprovalNotSupported();
error AmountIsZero();
error NotEnoughCollateral();
error DebtLowerThanTheFloor();
error RemainingDebtIsLowerThanTheFloor();
error TransferNotSupported();
error BurnFromNullAddress();
error BurnAmountExceedsBalance();
error MintToNullAddress();
error SurpassMaxDebtSupply();
error NewValueIsSameAsCurrent();
error SenderIsNotSmartFarmingManager();
/**
* @title Non-transferable token that represents users' debts
*/
contract DebtToken is ReentrancyGuard, TokenHolder, Manageable, DebtTokenStorageV2 {
using WadRayMath for uint256;
string public constant VERSION = "1.3.0";
uint256 public constant SECONDS_PER_YEAR = 365.25 days;
uint256 private constant HUNDRED_PERCENT = 1e18;
/// @notice Emitted when synthetic's debt is repaid
event DebtRepaid(address indexed payer, address indexed account, uint256 amount, uint256 repaid, uint256 fee);
/// @notice Emitted when active flag is updated
event DebtTokenActiveUpdated(bool newActive);
/// @notice Emitted when interest rate is updated
event InterestRateUpdated(uint256 oldInterestRate, uint256 newInterestRate);
/// @notice Emitted when max total supply is updated
event MaxTotalSupplyUpdated(uint256 oldMaxTotalSupply, uint256 newMaxTotalSupply);
/// @notice Emitted when synthetic token is issued
event SyntheticTokenIssued(
address indexed account,
address indexed to,
uint256 amount,
uint256 issued,
uint256 fee
);
/**
* @dev Throws if sender is not SmartFarmingManager
*/
modifier onlyIfSmartFarmingManager() {
if (msg.sender != address(pool.smartFarmingManager())) revert SenderIsNotSmartFarmingManager();
_;
}
/**
* @dev Throws if synthetic token doesn't exist
*/
modifier onlyIfSyntheticTokenExists() {
if (!pool.doesSyntheticTokenExist(syntheticToken)) revert SyntheticDoesNotExist();
_;
}
/**
* @dev Throws if debt token isn't enabled
*/
modifier onlyIfDebtTokenIsActive() {
if (!isActive) revert DebtTokenInactive();
_;
}
/**
* @dev Throws if synthetic token isn't enabled
*/
modifier onlyIfSyntheticTokenIsActive() {
if (!syntheticToken.isActive()) revert SyntheticIsInactive();
_;
}
/**
* @notice Update reward contracts' states
* @dev Should be called before balance changes (i.e. mint/burn)
*/
modifier updateRewardsBeforeMintOrBurn(address account_) {
address[] memory _rewardsDistributors = pool.getRewardsDistributors();
ISyntheticToken _syntheticToken = syntheticToken;
uint256 _length = _rewardsDistributors.length;
for (uint256 i; i < _length; ++i) {
IRewardsDistributor(_rewardsDistributors[i]).updateBeforeMintOrBurn(_syntheticToken, account_);
}
_;
}
constructor() {
_disableInitializers();
}
function initialize(
string calldata name_,
string calldata symbol_,
IPool pool_,
ISyntheticToken syntheticToken_,
uint256 interestRate_,
uint256 maxTotalSupply_
) external initializer {
if (bytes(name_).length == 0) revert NameIsNull();
if (bytes(symbol_).length == 0) revert SymbolIsNull();
if (address(pool_) == address(0)) revert PoolIsNull();
if (address(syntheticToken_) == address(0)) revert SyntheticIsNull();
__ReentrancyGuard_init();
__Manageable_init(pool_);
name = name_;
symbol = symbol_;
decimals = syntheticToken_.decimals();
syntheticToken = syntheticToken_;
lastTimestampAccrued = block.timestamp;
debtIndex = 1e18;
interestRate = interestRate_;
maxTotalSupply = maxTotalSupply_;
isActive = true;
}
/**
* @notice Accrue interest over debt supply
*/
function accrueInterest() public override {
(
uint256 _interestAmountAccrued,
uint256 _debtIndex,
uint256 _lastTimestampAccrued
) = _calculateInterestAccrual();
if (block.timestamp == _lastTimestampAccrued) {
return;
}
lastTimestampAccrued = block.timestamp;
if (_interestAmountAccrued > 0) {
totalSupply_ += _interestAmountAccrued;
debtIndex = _debtIndex;
// Note: Address states where minting will fail (e.g. the token is inactive, it reached max supply, etc)
try syntheticToken.mint(pool.feeCollector(), _interestAmountAccrued + pendingInterestFee) {
pendingInterestFee = 0;
} catch {
pendingInterestFee += _interestAmountAccrued;
}
}
}
/// @inheritdoc IERC20
function allowance(address /*owner_*/, address /*spender_*/) external pure override returns (uint256) {
revert AllowanceNotSupported();
}
/// @inheritdoc IERC20
// solhint-disable-next-line
function approve(address /*spender_*/, uint256 /*amount_*/) external override returns (bool) {
revert ApprovalNotSupported();
}
/**
* @notice Get the updated (principal + interest) user's debt
*/
function balanceOf(address account_) public view override returns (uint256) {
uint256 _principal = principalOf[account_];
if (_principal == 0) {
return 0;
}
(, uint256 _debtIndex, ) = _calculateInterestAccrual();
// Note: The `debtIndex / debtIndexOf` gives the interest to apply to the principal amount
return (_principal * _debtIndex) / debtIndexOf[account_];
}
/**
* @notice Burn debt token
* @param from_ The account to burn from
* @param amount_ The amount to burn
*/
function burn(address from_, uint256 amount_) external override onlyPool {
_burn(from_, amount_);
}
/**
* @notice Collect pending interest fee if any
*/
function collectPendingInterestFee() external {
uint256 _pendingInterestFee = pendingInterestFee;
if (_pendingInterestFee > 0) {
syntheticToken.mint(pool.feeCollector(), _pendingInterestFee);
pendingInterestFee = 0;
}
}
/**
* @notice Lock collateral and mint synthetic token
* @param amount_ The amount to mint
* @param to_ The beneficiary account
* @return _issued The amount issued after fees
* @return _fee The fee amount collected
*/
function issue(
uint256 amount_,
address to_
)
external
override
whenNotShutdown
nonReentrant
onlyIfSyntheticTokenExists
returns (uint256 _issued, uint256 _fee)
{
if (amount_ == 0) revert AmountIsZero();
accrueInterest();
IPool _pool = pool;
ISyntheticToken _syntheticToken = syntheticToken;
(, , , , uint256 _issuableInUsd) = _pool.debtPositionOf(msg.sender);
IMasterOracle _masterOracle = _pool.masterOracle();
if (amount_ > _masterOracle.quoteUsdToToken(address(_syntheticToken), _issuableInUsd)) {
revert NotEnoughCollateral();
}
_mint(_pool, _masterOracle, msg.sender, amount_);
(_issued, _fee) = quoteIssueOut(amount_);
if (_fee > 0) {
_syntheticToken.mint(_pool.feeCollector(), _fee);
}
_syntheticToken.mint(to_, _issued);
emit SyntheticTokenIssued(msg.sender, to_, amount_, _issued, _fee);
}
/**
* @notice Issue synth without checking collateral and without minting debt tokens
* @dev The healthy of outcome position must be done afterhand
* @param to_ The beneficiary account
* @param amount_ The amount to mint
* @return _issued The amount issued after fees
* @return _fee The fee amount collected
*/
function flashIssue(
address to_,
uint256 amount_
)
external
override
onlyIfSmartFarmingManager
whenNotShutdown
nonReentrant
onlyIfSyntheticTokenExists
onlyIfDebtTokenIsActive
returns (uint256 _issued, uint256 _fee)
{
if (amount_ == 0) revert AmountIsZero();
accrueInterest();
ISyntheticToken _syntheticToken = syntheticToken;
(_issued, _fee) = quoteIssueOut(amount_);
if (_fee > 0) {
_syntheticToken.mint(pool.feeCollector(), _fee);
}
_syntheticToken.mint(to_, _issued);
}
/**
* @notice Return interest rate (in percent) per second
*/
function interestRatePerSecond() public view override returns (uint256) {
return interestRate / SECONDS_PER_YEAR;
}
/**
* @notice onlySmartFarmingManager:: Mint `amount_` of debtToken at `to_`.
* @param to_ Receiver address
* @param amount_ Token amount to mint
*/
function mint(
address to_,
uint256 amount_
)
external
override
onlyIfSmartFarmingManager
whenNotShutdown
nonReentrant
onlyIfSyntheticTokenExists
onlyIfSyntheticTokenIsActive
{
accrueInterest();
IPool _pool = pool;
_mint(_pool, _pool.masterOracle(), to_, amount_);
}
/**
* @notice Quote gross `_amount` to issue `amountToIssue_` synthetic tokens
* @param amountToIssue_ Synth to issue
* @return _amount Gross amount
* @return _fee The fee amount to collect
*/
function quoteIssueIn(uint256 amountToIssue_) external view override returns (uint256 _amount, uint256 _fee) {
uint256 _issueFee = pool.feeProvider().issueFee();
if (_issueFee == 0) {
return (amountToIssue_, _fee);
}
_amount = amountToIssue_.wadDiv(HUNDRED_PERCENT - _issueFee);
_fee = _amount - amountToIssue_;
}
/**
* @notice Quote synthetic tokens `_amountToIssue` by using gross `_amount`
* @param amount_ Gross amount
* @return _amountToIssue Synth to issue
* @return _fee The fee amount to collect
*/
function quoteIssueOut(uint256 amount_) public view override returns (uint256 _amountToIssue, uint256 _fee) {
uint256 _issueFee = pool.feeProvider().issueFee();
if (_issueFee == 0) {
return (amount_, _fee);
}
_fee = amount_.wadMul(_issueFee);
_amountToIssue = amount_ - _fee;
}
/**
* @notice Quote synthetic token `_amount` need to repay `amountToRepay_` debt
* @param amountToRepay_ Debt amount to repay
* @return _amount Gross amount
* @return _fee The fee amount to collect
*/
function quoteRepayIn(uint256 amountToRepay_) public view override returns (uint256 _amount, uint256 _fee) {
uint256 _repayFee = pool.feeProvider().repayFee();
if (_repayFee == 0) {
return (amountToRepay_, _fee);
}
_fee = amountToRepay_.wadMul(_repayFee);
_amount = amountToRepay_ + _fee;
}
/**
* @notice Quote debt `_amountToRepay` by burning `_amount` synthetic tokens
* @param amount_ Gross amount
* @return _amountToRepay Debt amount to repay
* @return _fee The fee amount to collect
*/
function quoteRepayOut(uint256 amount_) public view override returns (uint256 _amountToRepay, uint256 _fee) {
uint256 _repayFee = pool.feeProvider().repayFee();
if (_repayFee == 0) {
return (amount_, _fee);
}
_amountToRepay = amount_.wadDiv(HUNDRED_PERCENT + _repayFee);
_fee = amount_ - _amountToRepay;
}
/**
* @notice Send synthetic token to decrease debt
* @dev The msg.sender is the payer and the account beneficed
* @param onBehalfOf_ The account that will have debt decreased
* @param amount_ The amount of synthetic token to burn (this is the gross amount, the repay fee will be subtracted from it)
* @return _repaid The amount repaid after fees
*/
function repay(
address onBehalfOf_,
uint256 amount_
)
external
override
whenNotShutdown
nonReentrant
onlyIfSyntheticTokenExists
returns (uint256 _repaid, uint256 _fee)
{
if (amount_ == 0) revert AmountIsZero();
accrueInterest();
IPool _pool = pool;
ISyntheticToken _syntheticToken = syntheticToken;
(_repaid, _fee) = quoteRepayOut(amount_);
if (_fee > 0) {
_syntheticToken.seize(msg.sender, _pool.feeCollector(), _fee);
}
uint256 _debtFloorInUsd = _pool.debtFloorInUsd();
if (_debtFloorInUsd > 0) {
uint256 _newDebtInUsd = _pool.masterOracle().quoteTokenToUsd(
address(_syntheticToken),
balanceOf(onBehalfOf_) - _repaid
);
if (_newDebtInUsd > 0 && _newDebtInUsd < _debtFloorInUsd) {
revert RemainingDebtIsLowerThanTheFloor();
}
}
_syntheticToken.burn(msg.sender, _repaid);
_burn(onBehalfOf_, _repaid);
emit DebtRepaid(msg.sender, onBehalfOf_, amount_, _repaid, _fee);
}
/**
* @notice Send synthetic token to decrease debt
* @dev This function helps users to no leave debt dust behind
* @param onBehalfOf_ The account that will have debt decreased
* @return _repaid The amount repaid after fees
* @return _fee The fee amount collected
*/
function repayAll(
address onBehalfOf_
)
external
override
whenNotShutdown
nonReentrant
onlyIfSyntheticTokenExists
returns (uint256 _repaid, uint256 _fee)
{
accrueInterest();
_repaid = balanceOf(onBehalfOf_);
if (_repaid == 0) revert AmountIsZero();
ISyntheticToken _syntheticToken = syntheticToken;
uint256 _amount;
(_amount, _fee) = quoteRepayIn(_repaid);
if (_fee > 0) {
_syntheticToken.seize(msg.sender, pool.feeCollector(), _fee);
}
_syntheticToken.burn(msg.sender, _repaid);
_burn(onBehalfOf_, _repaid);
emit DebtRepaid(msg.sender, onBehalfOf_, _amount, _repaid, _fee);
}
/**
* @notice Return the total supply
*/
function totalSupply() external view override returns (uint256) {
(uint256 _interestAmountAccrued, , ) = _calculateInterestAccrual();
return totalSupply_ + _interestAmountAccrued;
}
/// @inheritdoc IERC20
// solhint-disable-next-line
function transfer(address /*recipient_*/, uint256 /*amount_*/) external override returns (bool) {
revert TransferNotSupported();
}
/// @inheritdoc IERC20
// solhint-disable-next-line
function transferFrom(
address /*sender_*/,
address /*recipient_*/,
uint256 /*amount_*/
) external override returns (bool) {
revert TransferNotSupported();
}
/**
* @notice Destroy `amount` tokens from `account`, reducing the
* total supply
*/
function _burn(address account_, uint256 amount_) private updateRewardsBeforeMintOrBurn(account_) {
if (account_ == address(0)) revert BurnFromNullAddress();
uint256 _accountBalance = balanceOf(account_);
if (_accountBalance < amount_) revert BurnAmountExceedsBalance();
unchecked {
principalOf[account_] = _accountBalance - amount_;
debtIndexOf[account_] = debtIndex;
totalSupply_ -= amount_;
}
emit Transfer(account_, address(0), amount_);
// Remove this token from the debt tokens list if the sender's balance goes to zero
if (amount_ > 0 && balanceOf(account_) == 0) {
pool.removeFromDebtTokensOfAccount(account_);
}
}
/**
* @notice Calculate interest to accrue
* @dev This util function avoids code duplication across `balanceOf` and `accrueInterest`
* @return _interestAmountAccrued The total amount of debt tokens accrued
* @return _debtIndex The new `debtIndex` value
*/
function _calculateInterestAccrual()
private
view
returns (uint256 _interestAmountAccrued, uint256 _debtIndex, uint256 _lastTimestampAccrued)
{
_lastTimestampAccrued = lastTimestampAccrued;
_debtIndex = debtIndex;
if (block.timestamp > _lastTimestampAccrued) {
uint256 _interestRateToAccrue = interestRatePerSecond() * (block.timestamp - _lastTimestampAccrued);
if (_interestRateToAccrue > 0) {
_interestAmountAccrued = _interestRateToAccrue.wadMul(totalSupply_);
_debtIndex += _interestRateToAccrue.wadMul(debtIndex);
}
}
}
/**
* @dev Create `amount` tokens and assigns them to `account`, increasing
* the total supply
*/
function _mint(
IPool pool_,
IMasterOracle masterOracle_,
address account_,
uint256 amount_
) private onlyIfDebtTokenIsActive updateRewardsBeforeMintOrBurn(account_) {
if (account_ == address(0)) revert MintToNullAddress();
uint256 _debtFloorInUsd = pool_.debtFloorInUsd();
uint256 _balanceBefore = balanceOf(account_);
if (
_debtFloorInUsd > 0 &&
masterOracle_.quoteTokenToUsd(address(syntheticToken), _balanceBefore + amount_) < _debtFloorInUsd
) {
revert DebtLowerThanTheFloor();
}
totalSupply_ += amount_;
if (totalSupply_ > maxTotalSupply) revert SurpassMaxDebtSupply();
principalOf[account_] = _balanceBefore + amount_;
debtIndexOf[account_] = debtIndex;
emit Transfer(address(0), account_, amount_);
// Add this token to the debt tokens list if the recipient is receiving it for the 1st time
if (_balanceBefore == 0 && amount_ > 0) {
pool.addToDebtTokensOfAccount(account_);
}
}
/// @inheritdoc TokenHolder
// solhint-disable-next-line no-empty-blocks
function _requireCanSweep() internal view override onlyGovernor {}
/**
* @notice Update max total supply
*/
function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external override onlyGovernor {
uint256 _currentMaxTotalSupply = maxTotalSupply;
if (newMaxTotalSupply_ == _currentMaxTotalSupply) revert NewValueIsSameAsCurrent();
emit MaxTotalSupplyUpdated(_currentMaxTotalSupply, newMaxTotalSupply_);
maxTotalSupply = newMaxTotalSupply_;
}
/**
* @notice Update interest rate (APR)
*/
function updateInterestRate(uint256 newInterestRate_) external override onlyGovernor {
accrueInterest();
uint256 _currentInterestRate = interestRate;
if (newInterestRate_ == _currentInterestRate) revert NewValueIsSameAsCurrent();
emit InterestRateUpdated(_currentInterestRate, newInterestRate_);
interestRate = newInterestRate_;
}
/**
* @notice Enable/Disable the Debt Token
*/
function toggleIsActive() external override onlyGovernor {
bool _newIsActive = !isActive;
emit DebtTokenActiveUpdated(_newIsActive);
isActive = _newIsActive;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "../dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol";
import "../interfaces/IGovernable.sol";
import "../interfaces/IManageable.sol";
error SenderIsNotPool();
error SenderIsNotGovernor();
error IsPaused();
error IsShutdown();
error PoolAddressIsNull();
/**
* @title Reusable contract that handles accesses
*/
abstract contract Manageable is IManageable, Initializable {
/**
* @notice Pool contract
*/
IPool public pool;
/**
* @dev Throws if `msg.sender` isn't the pool
*/
modifier onlyPool() {
if (msg.sender != address(pool)) revert SenderIsNotPool();
_;
}
/**
* @dev Throws if `msg.sender` isn't the governor
*/
modifier onlyGovernor() {
if (msg.sender != governor()) revert SenderIsNotGovernor();
_;
}
/**
* @dev Throws if contract is paused
*/
modifier whenNotPaused() {
if (pool.paused()) revert IsPaused();
_;
}
/**
* @dev Throws if contract is shutdown
*/
modifier whenNotShutdown() {
if (pool.everythingStopped()) revert IsShutdown();
_;
}
// solhint-disable-next-line func-name-mixedcase
function __Manageable_init(IPool pool_) internal onlyInitializing {
if (address(pool_) == address(0)) revert PoolAddressIsNull();
pool = pool_;
}
/**
* @notice Get the governor
* @return _governor The governor
*/
function governor() public view returns (address _governor) {
_governor = IGovernable(address(pool)).governor();
}
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "../../../../../openzeppelin-upgradeable/utils/introspection/IERC165Upgradeable.sol";
/**
* @dev Interface of the IOFT core standard
*/
interface IOFTCoreUpgradeable is IERC165Upgradeable {
/**
* @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)
* _dstChainId - L0 defined chain id to send tokens too
* _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain
* _amount - amount of the tokens to transfer
* _useZro - indicates to use zro to pay L0 fees
* _adapterParam - flexible bytes array to indicate messaging adapter services in L0
*/
function estimateSendFee(
uint16 _dstChainId,
bytes calldata _toAddress,
uint _amount,
bool _useZro,
bytes calldata _adapterParams
) external view returns (uint nativeFee, uint zroFee);
/**
* @dev send `_amount` amount of token to (`_dstChainId`, `_toAddress`) from `_from`
* `_from` the owner of token
* `_dstChainId` the destination chain identifier
* `_toAddress` can be any size depending on the `dstChainId`.
* `_amount` the quantity of tokens in wei
* `_refundAddress` the address LayerZero refunds if too much message fee is sent
* `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
* `_adapterParams` is a flexible bytes array to indicate messaging adapter services
*/
function sendFrom(
address _from,
uint16 _dstChainId,
bytes calldata _toAddress,
uint _amount,
address payable _refundAddress,
address _zroPaymentAddress,
bytes calldata _adapterParams
) external payable;
/**
* @dev returns the circulating amount of tokens on current chain
*/
function circulatingSupply() external view returns (uint);
/**
* @dev returns the address of the ERC20 token
*/
function token() external view returns (address);
/**
* @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)
* `_nonce` is the outbound nonce
*/
event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes _toAddress, uint _amount);
/**
* @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.
* `_nonce` is the inbound nonce.
*/
event ReceiveFromChain(uint16 indexed _srcChainId, address indexed _to, uint _amount);
event SetUseCustomAdapterParams(bool _useCustomAdapterParams);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;
import "../IOFTCoreUpgradeable.sol";
/**
* @dev Interface of the composable OFT core standard
*/
interface IComposableOFTCoreUpgradeable is IOFTCoreUpgradeable {
function estimateSendAndCallFee(
uint16 _dstChainId,
bytes calldata _toAddress,
uint _amount,
bytes calldata _payload,
uint64 _dstGasForCall,
bool _useZro,
bytes calldata _adapterParams
) external view returns (uint nativeFee, uint zroFee);
function sendAndCall(
address _from,
uint16 _dstChainId,
bytes calldata _toAddress,
uint _amount,
bytes calldata _payload,
uint64 _dstGasForCall,
address payable _refundAddress,
address _zroPaymentAddress,
bytes calldata _adapterParams
) external payable;
function retryOFTReceived(
uint16 _srcChainId,
bytes calldata _srcAddress,
uint64 _nonce,
bytes calldata _from,
address _to,
uint _amount,
bytes calldata _payload
) external;
event CallOFTReceivedFailure(
uint16 indexed _srcChainId,
bytes _srcAddress,
uint64 _nonce,
bytes _from,
address indexed _to,
uint _amount,
bytes _payload,
bytes _reason
);
event CallOFTReceivedSuccess(uint16 indexed _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _hash);
event RetryOFTReceivedSuccess(bytes32 _messageHash);
event NonContractAddress(address _address);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;
interface IOFTReceiverUpgradeable {
/**
* @dev Called by the OFT contract when tokens are received from source chain.
* @param _srcChainId The chain id of the source chain.
* @param _srcAddress The address of the OFT token contract on the source chain.
* @param _nonce The nonce of the transaction on the source chain.
* @param _from The address of the account who calls the sendAndCall() on the source chain.
* @param _amount The amount of tokens to transfer.
* @param _payload Additional data with no specified format.
*/
function onOFTReceived(
uint16 _srcChainId,
bytes calldata _srcAddress,
uint64 _nonce,
bytes calldata _from,
uint _amount,
bytes calldata _payload
) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.
*/
modifier initializer() {
bool isTopLevelCall = _setInitializedVersion(1);
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original
* initialization step. This is essential to configure modules that are added through upgrades and that require
* initialization.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*/
modifier reinitializer(uint8 version) {
bool isTopLevelCall = _setInitializedVersion(version);
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(version);
}
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*/
function _disableInitializers() internal virtual {
_setInitializedVersion(type(uint8).max);
}
function _setInitializedVersion(uint8 version) private returns (bool) {
// If the contract is initializing we ignore whether _initialized is set in order to support multiple
// inheritance patterns, but we only do this in the context of a constructor, and for the lowest level
// of initializers, because in other contexts the contract may have been reentered.
if (_initializing) {
require(
version == 1 && !AddressUpgradeable.isContract(address(this)),
"Initializable: contract is already initialized"
);
return false;
} else {
require(_initialized < version, "Initializable: contract is already initialized");
_initialized = version;
return true;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165Upgradeable {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^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.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../IERC20.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 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'
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) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(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
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library 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
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev 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");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.9;
import "./IStargateRouter.sol";
interface IStargateComposer {
function swap(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
uint256 _amountLD,
uint256 _minAmountLD,
IStargateRouter.lzTxObj memory _lzTxParams,
bytes calldata _to,
bytes calldata _payload
) external payable;
function factory() external view returns (address);
function stargateBridge() external view returns (address);
function stargateRouter() external view returns (IStargateRouter);
function quoteLayerZeroFee(
uint16 _dstChainId,
uint8 _functionType,
bytes calldata _toAddress,
bytes calldata _transferAndCallPayload,
IStargateRouter.lzTxObj memory _lzTxParams
) external view returns (uint256, uint256);
function peers(uint16 _chainId) external view returns (address);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.9;
interface IStargateReceiver {
function sgReceive(
uint16 _chainId,
bytes memory _srcAddress,
uint256 _nonce,
address _token,
uint256 amountLD,
bytes memory payload
) external;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.9;
interface IStargateRouter {
struct lzTxObj {
uint256 dstGasForCall;
uint256 dstNativeAmount;
bytes dstNativeAddr;
}
function addLiquidity(uint256 _poolId, uint256 _amountLD, address _to) external;
function swap(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
uint256 _amountLD,
uint256 _minAmountLD,
lzTxObj memory _lzTxParams,
bytes calldata _to,
bytes calldata _payload
) external payable;
function redeemRemote(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
uint256 _amountLP,
uint256 _minAmountLD,
bytes calldata _to,
lzTxObj memory _lzTxParams
) external payable;
function instantRedeemLocal(uint16 _srcPoolId, uint256 _amountLP, address _to) external returns (uint256);
function redeemLocal(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
uint256 _amountLP,
bytes calldata _to,
lzTxObj memory _lzTxParams
) external payable;
function sendCredits(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress
) external payable;
function quoteLayerZeroFee(
uint16 _dstChainId,
uint8 _functionType,
bytes calldata _toAddress,
bytes calldata _transferAndCallPayload,
lzTxObj memory _lzTxParams
) external view returns (uint256, uint256);
function clearCachedSwap(uint16 _srcChainId, bytes calldata _srcAddress, uint256 _nonce) external;
function factory() external view returns (address);
function bridge() external view returns (address);
function cachedSwapLookup(
uint16 _chainId_,
bytes calldata _srcAddress,
uint256 _nonce
) external view returns (address token, uint256 amountLD, address to, bytes memory payload);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "../dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/token/oft/composable/IOFTReceiverUpgradeable.sol";
import "../dependencies/stargate-protocol/interfaces/IStargateReceiver.sol";
import "../dependencies/stargate-protocol/interfaces/IStargateRouter.sol";
import "../dependencies/stargate-protocol/interfaces/IStargateComposer.sol";
import "./IProxyOFT.sol";
interface ICrossChainDispatcher is IStargateReceiver, IOFTReceiverUpgradeable {
function crossChainDispatcherOf(uint16 chainId_) external view returns (address);
function triggerFlashRepaySwap(
uint256 id_,
address payable account_,
address tokenIn_,
address tokenOut_,
uint256 amountIn_,
uint256 amountOutMin_,
bytes calldata lzArgs_
) external payable;
function triggerLeverageSwap(
uint256 id_,
address payable account_,
address tokenIn_,
address tokenOut_,
uint256 amountIn_,
uint256 amountOutMin,
bytes calldata lzArgs_
) external payable;
function isBridgingActive() external view returns (bool);
function flashRepayCallbackTxGasLimit() external view returns (uint64);
function flashRepaySwapTxGasLimit() external view returns (uint64);
function leverageCallbackTxGasLimit() external view returns (uint64);
function leverageSwapTxGasLimit() external view returns (uint64);
function lzBaseGasLimit() external view returns (uint256);
function stargateComposer() external view returns (IStargateComposer);
function stargateSlippage() external view returns (uint256);
function stargatePoolIdOf(address token_) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol";
import "./ISyntheticToken.sol";
interface IDebtToken is IERC20Metadata {
function lastTimestampAccrued() external view returns (uint256);
function isActive() external view returns (bool);
function syntheticToken() external view returns (ISyntheticToken);
function accrueInterest() external;
function debtIndex() external returns (uint256 debtIndex_);
function burn(address from_, uint256 amount_) external;
function issue(uint256 amount_, address to_) external returns (uint256 _issued, uint256 _fee);
function flashIssue(address to_, uint256 amount_) external returns (uint256 _issued, uint256 _fee);
function mint(address to_, uint256 amount_) external;
function repay(address onBehalfOf_, uint256 amount_) external returns (uint256 _repaid, uint256 _fee);
function repayAll(address onBehalfOf_) external returns (uint256 _repaid, uint256 _fee);
function quoteIssueIn(uint256 amountToIssue_) external view returns (uint256 _amount, uint256 _fee);
function quoteIssueOut(uint256 amount_) external view returns (uint256 _amountToIssue, uint256 _fee);
function quoteRepayIn(uint256 amountToRepay_) external view returns (uint256 _amount, uint256 _fee);
function quoteRepayOut(uint256 amount_) external view returns (uint256 _amountToRepay, uint256 _fee);
function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external;
function updateInterestRate(uint256 newInterestRate_) external;
function maxTotalSupply() external view returns (uint256);
function interestRate() external view returns (uint256);
function interestRatePerSecond() external view returns (uint256);
function toggleIsActive() external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol";
interface IDepositToken is IERC20Metadata {
function underlying() external view returns (IERC20);
function collateralFactor() external view returns (uint256);
function unlockedBalanceOf(address account_) external view returns (uint256);
function lockedBalanceOf(address account_) external view returns (uint256);
function flashWithdraw(address account_, uint256 amount_) external returns (uint256 _withdrawn, uint256 _fee);
function deposit(uint256 amount_, address onBehalfOf_) external returns (uint256 _deposited, uint256 _fee);
function quoteDepositIn(uint256 amountToDeposit_) external view returns (uint256 _amount, uint256 _fee);
function quoteDepositOut(uint256 amount_) external view returns (uint256 _amountToDeposit, uint256 _fee);
function quoteWithdrawIn(uint256 amountToWithdraw_) external view returns (uint256 _amount, uint256 _fee);
function quoteWithdrawOut(uint256 amount_) external view returns (uint256 _amountToWithdraw, uint256 _fee);
function withdraw(uint256 amount_, address to_) external returns (uint256 _withdrawn, uint256 _fee);
function seize(address from_, address to_, uint256 amount_) external;
function updateCollateralFactor(uint128 newCollateralFactor_) external;
function isActive() external view returns (bool);
function toggleIsActive() external;
function maxTotalSupply() external view returns (uint256);
function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external;
function withdrawFrom(address from_, uint256 amount_) external returns (uint256 _withdrawn, uint256 _fee);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
/**
* @notice FeeProvider interface
*/
interface IFeeProvider {
struct LiquidationFees {
uint128 liquidatorIncentive;
uint128 protocolFee;
}
function defaultSwapFee() external view returns (uint256);
function depositFee() external view returns (uint256);
function issueFee() external view returns (uint256);
function liquidationFees() external view returns (uint128 liquidatorIncentive, uint128 protocolFee);
function repayFee() external view returns (uint256);
function swapFeeFor(address account_) external view returns (uint256);
function withdrawFee() external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
/**
* @notice Governable interface
*/
interface IGovernable {
function governor() external view returns (address _governor);
function transferGovernorship(address _proposedGovernor) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "./IPool.sol";
/**
* @notice Manageable interface
*/
interface IManageable {
function pool() external view returns (IPool _pool);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
interface IPauseable {
function paused() external view returns (bool);
function everythingStopped() external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "./IDepositToken.sol";
import "./IDebtToken.sol";
import "./ITreasury.sol";
import "./IRewardsDistributor.sol";
import "./IPoolRegistry.sol";
import "./IFeeProvider.sol";
import "./ISmartFarmingManager.sol";
import "./external/ISwapper.sol";
import "../interfaces/IFeeProvider.sol";
/**
* @notice Pool interface
*/
interface IPool is IPauseable, IGovernable {
function debtFloorInUsd() external view returns (uint256);
function feeCollector() external view returns (address);
function feeProvider() external view returns (IFeeProvider);
function maxLiquidable() external view returns (uint256);
function doesSyntheticTokenExist(ISyntheticToken syntheticToken_) external view returns (bool);
function doesDebtTokenExist(IDebtToken debtToken_) external view returns (bool);
function doesDepositTokenExist(IDepositToken depositToken_) external view returns (bool);
function depositTokenOf(IERC20 underlying_) external view returns (IDepositToken);
function debtTokenOf(ISyntheticToken syntheticToken_) external view returns (IDebtToken);
function getDepositTokens() external view returns (address[] memory);
function getDebtTokens() external view returns (address[] memory);
function getRewardsDistributors() external view returns (address[] memory);
function debtOf(address account_) external view returns (uint256 _debtInUsd);
function depositOf(address account_) external view returns (uint256 _depositInUsd, uint256 _issuableLimitInUsd);
function debtPositionOf(
address account_
)
external
view
returns (
bool _isHealthy,
uint256 _depositInUsd,
uint256 _debtInUsd,
uint256 _issuableLimitInUsd,
uint256 _issuableInUsd
);
function liquidate(
ISyntheticToken syntheticToken_,
address account_,
uint256 amountToRepay_,
IDepositToken depositToken_
) external returns (uint256 _totalSeized, uint256 _toLiquidator, uint256 _fee);
function quoteLiquidateIn(
ISyntheticToken syntheticToken_,
uint256 totalToSeized_,
IDepositToken depositToken_
) external view returns (uint256 _amountToRepay, uint256 _toLiquidator, uint256 _fee);
function quoteLiquidateMax(
ISyntheticToken syntheticToken_,
address account_,
IDepositToken depositToken_
) external view returns (uint256 _maxAmountToRepay);
function quoteLiquidateOut(
ISyntheticToken syntheticToken_,
uint256 amountToRepay_,
IDepositToken depositToken_
) external view returns (uint256 _totalSeized, uint256 _toLiquidator, uint256 _fee);
function quoteSwapIn(
ISyntheticToken syntheticTokenIn_,
ISyntheticToken syntheticTokenOut_,
uint256 amountOut_
) external view returns (uint256 _amountIn, uint256 _fee);
function quoteSwapOut(
ISyntheticToken syntheticTokenIn_,
ISyntheticToken syntheticTokenOut_,
uint256 amountIn_
) external view returns (uint256 _amountOut, uint256 _fee);
function swap(
ISyntheticToken syntheticTokenIn_,
ISyntheticToken syntheticTokenOut_,
uint256 amountIn_
) external returns (uint256 _amountOut, uint256 _fee);
function treasury() external view returns (ITreasury);
function masterOracle() external view returns (IMasterOracle);
function poolRegistry() external view returns (IPoolRegistry);
function addToDepositTokensOfAccount(address account_) external;
function removeFromDepositTokensOfAccount(address account_) external;
function addToDebtTokensOfAccount(address account_) external;
function removeFromDebtTokensOfAccount(address account_) external;
function getDepositTokensOfAccount(address account_) external view returns (address[] memory);
function getDebtTokensOfAccount(address account_) external view returns (address[] memory);
function isSwapActive() external view returns (bool);
function smartFarmingManager() external view returns (ISmartFarmingManager);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "./external/IMasterOracle.sol";
import "./IPauseable.sol";
import "./IGovernable.sol";
import "./ISyntheticToken.sol";
import "./external/ISwapper.sol";
import "./IQuoter.sol";
import "./ICrossChainDispatcher.sol";
interface IPoolRegistry is IPauseable, IGovernable {
function feeCollector() external view returns (address);
function isPoolRegistered(address pool_) external view returns (bool);
function nativeTokenGateway() external view returns (address);
function getPools() external view returns (address[] memory);
function registerPool(address pool_) external;
function unregisterPool(address pool_) external;
function masterOracle() external view returns (IMasterOracle);
function updateFeeCollector(address newFeeCollector_) external;
function idOfPool(address pool_) external view returns (uint256);
function nextPoolId() external view returns (uint256);
function swapper() external view returns (ISwapper);
function quoter() external view returns (IQuoter);
function crossChainDispatcher() external view returns (ICrossChainDispatcher);
function doesSyntheticTokenExist(ISyntheticToken syntheticToken_) external view returns (bool _exists);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "../dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/token/oft/composable/IComposableOFTCoreUpgradeable.sol";
interface IProxyOFT is IComposableOFTCoreUpgradeable {
function getProxyOFTOf(uint16 chainId_) external view returns (address _proxyOFT);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "./IPoolRegistry.sol";
import "./IProxyOFT.sol";
interface IQuoter {
function quoteCrossChainFlashRepayNativeFee(
IProxyOFT proxyOFT_,
bytes calldata lzArgs_
) external view returns (uint256 _nativeFee);
function quoteCrossChainLeverageNativeFee(
IProxyOFT proxyOFT_,
bytes calldata lzArgs_
) external view returns (uint256 _nativeFee);
function quoteLeverageCallbackNativeFee(uint16 dstChainId_) external view returns (uint256 _callbackTxNativeFee);
function quoteFlashRepayCallbackNativeFee(uint16 dstChainId_) external view returns (uint256 _callbackTxNativeFee);
function getFlashRepaySwapAndCallbackLzArgs(
uint16 srcChainId_,
uint16 dstChainId_
) external view returns (bytes memory lzArgs_);
function getLeverageSwapAndCallbackLzArgs(
uint16 srcChainId_,
uint16 dstChainId_
) external view returns (bytes memory lzArgs_);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "../dependencies/openzeppelin/token/ERC20/IERC20.sol";
/**
* @notice Reward Distributor interface
*/
interface IRewardsDistributor {
function rewardToken() external view returns (IERC20);
function tokenSpeeds(IERC20 token_) external view returns (uint256);
function tokensAccruedOf(address account_) external view returns (uint256);
function updateBeforeMintOrBurn(IERC20 token_, address account_) external;
function updateBeforeTransfer(IERC20 token_, address from_, address to_) external;
function claimable(address account_) external view returns (uint256 _claimable);
function claimable(address account_, IERC20 token_) external view returns (uint256 _claimable);
function claimRewards(address account_) external;
function claimRewards(address account_, IERC20[] memory tokens_) external;
function claimRewards(address[] memory accounts_, IERC20[] memory tokens_) external;
function updateTokenSpeed(IERC20 token_, uint256 newSpeed_) external;
function updateTokenSpeeds(IERC20[] calldata tokens_, uint256[] calldata speeds_) external;
function tokens(uint256) external view returns (IERC20);
function tokenStates(IERC20) external view returns (uint224 index, uint32 timestamp);
function accountIndexOf(IERC20, address) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "./IManageable.sol";
import "./IDepositToken.sol";
import "./IDebtToken.sol";
/**
* @notice SmartFarmingManager interface
*/
interface ISmartFarmingManager {
function flashRepay(
ISyntheticToken syntheticToken_,
IDepositToken depositToken_,
uint256 withdrawAmount_,
uint256 repayAmountMin_
) external returns (uint256 _withdrawn, uint256 _repaid);
function crossChainFlashRepay(
ISyntheticToken syntheticToken_,
IDepositToken depositToken_,
uint256 withdrawAmount_,
IERC20 bridgeToken_,
uint256 bridgeTokenAmountMin_,
uint256 swapAmountOutMin_,
uint256 repayAmountMin_,
bytes calldata lzArgs_
) external payable;
function crossChainLeverage(
IERC20 tokenIn_,
IDepositToken depositToken_,
ISyntheticToken syntheticToken_,
uint256 amountIn_,
uint256 leverage_,
uint256 swapAmountOutMin_,
uint256 depositAmountMin_,
bytes calldata lzArgs_
) external payable;
function crossChainLeverageCallback(uint256 id_, uint256 swapAmountOut_) external returns (uint256 _deposited);
function crossChainFlashRepayCallback(uint256 id_, uint256 swapAmountOut_) external returns (uint256 _repaid);
function leverage(
IERC20 tokenIn_,
IDepositToken depositToken_,
ISyntheticToken syntheticToken_,
uint256 amountIn_,
uint256 leverage_,
uint256 depositAmountMin_
) external returns (uint256 _deposited, uint256 _issued);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol";
import "./IDebtToken.sol";
import "./IPoolRegistry.sol";
import "../interfaces/IProxyOFT.sol";
interface ISyntheticToken is IERC20Metadata {
function isActive() external view returns (bool);
function mint(address to_, uint256 amount_) external;
function burn(address from_, uint256 amount) external;
function poolRegistry() external view returns (IPoolRegistry);
function toggleIsActive() external;
function seize(address from_, address to_, uint256 amount_) external;
function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external;
function updateProxyOFT(IProxyOFT newProxyOFT_) external;
function maxTotalSupply() external view returns (uint256);
function proxyOFT() external view returns (IProxyOFT);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
interface ITreasury {
function pull(address to_, uint256 amount_) external;
function migrateTo(address newTreasury_) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
interface IMasterOracle {
function quoteTokenToUsd(address _asset, uint256 _amount) external view returns (uint256 _amountInUsd);
function quoteUsdToToken(address _asset, uint256 _amountInUsd) external view returns (uint256 _amount);
function quote(address _assetIn, address _assetOut, uint256 _amountIn) external view returns (uint256 _amountOut);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
interface ISwapper {
function swapExactInput(
address tokenIn_,
address tokenOut_,
uint256 amountIn_,
uint256 amountOutMin_,
address receiver_
) external returns (uint256 _amountOut);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
/**
* @title Math library
* @dev Provides mul and div function for wads (decimal numbers with 18 digits precision) and rays (decimals with 27 digits)
* @dev Based on https://github.com/dapphub/ds-math/blob/master/src/math.sol
*/
library WadRayMath {
uint256 internal constant WAD = 1e18;
uint256 internal constant HALF_WAD = WAD / 2;
uint256 internal constant RAY = 1e27;
uint256 internal constant HALF_RAY = RAY / 2;
uint256 internal constant WAD_RAY_RATIO = 1e9;
/**
* @dev Multiplies two wad, rounding half up to the nearest wad
* @param a Wad
* @param b Wad
* @return The result of a*b, in wad
*/
function wadMul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0 || b == 0) {
return 0;
}
return (a * b + HALF_WAD) / WAD;
}
/**
* @dev Divides two wad, rounding half up to the nearest wad
* @param a Wad
* @param b Wad
* @return The result of a/b, in wad
*/
function wadDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return (a * WAD + b / 2) / b;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "../interfaces/IDebtToken.sol";
abstract contract DebtTokenStorageV1 is IDebtToken {
/**
* @notice The name of the token
*/
string public override name;
/**
* @notice The symbol of the token
*/
string public override symbol;
/**
* @notice The mapping of the users' minted tokens
* @dev This value changes within the mint and burn operations
*/
mapping(address => uint256) internal principalOf;
/**
* @notice The `debtIndex` "snapshot" of the account's latest `principalOf` update (i.e. mint/burn)
*/
mapping(address => uint256) internal debtIndexOf;
/**
* @notice The supply cap
*/
uint256 public override maxTotalSupply;
/**
* @notice The total amount of minted tokens
*/
uint256 internal totalSupply_;
/**
* @notice The timestamp when interest accrual was calculated for the last time
*/
uint256 public override lastTimestampAccrued;
/**
* @notice Accumulator of the total earned interest rate since the beginning
*/
uint256 public override debtIndex;
/**
* @notice Interest rate
* @dev Use 0.1e18 for 10% APR
*/
uint256 public override interestRate;
/**
* @notice The Synthetic token
*/
ISyntheticToken public override syntheticToken;
/**
* @notice If true, disables msAsset minting on this pool
*/
bool public override isActive;
/**
* @notice The decimals of the token
*/
uint8 public override decimals;
}
abstract contract DebtTokenStorageV2 is DebtTokenStorageV1 {
/**
* @notice Pending interest fee to collect
*/
uint256 public pendingInterestFee;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
import "../dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol";
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard is Initializable {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
function __ReentrancyGuard_init() internal onlyInitializing {
__ReentrancyGuard_init_unchained();
}
function __ReentrancyGuard_init_unchained() internal onlyInitializing {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "../dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol";
error FallbackIsNotAllowed();
error ReceiveIsNotAllowed();
/**
* @title Utils contract that handles tokens sent to it
*/
abstract contract TokenHolder {
using SafeERC20 for IERC20;
/**
* @dev Revert fallback calls
*/
fallback() external payable {
revert FallbackIsNotAllowed();
}
/**
* @dev Revert when receiving by default
*/
receive() external payable virtual {
revert ReceiveIsNotAllowed();
}
/**
* @notice ERC20 recovery in case of stuck tokens due direct transfers to the contract address.
* @param token_ The token to transfer
* @param to_ The recipient of the transfer
* @param amount_ The amount to send
*/
function sweep(IERC20 token_, address to_, uint256 amount_) external {
_requireCanSweep();
if (address(token_) == address(0)) {
Address.sendValue(payable(to_), amount_);
} else {
token_.safeTransfer(to_, amount_);
}
}
/**
* @notice Function that reverts if the caller isn't allowed to sweep tokens
* @dev Usually requires the owner or governor as the caller
*/
function _requireCanSweep() internal view virtual;
}{
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [],
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AllowanceNotSupported","type":"error"},{"inputs":[],"name":"AmountIsZero","type":"error"},{"inputs":[],"name":"ApprovalNotSupported","type":"error"},{"inputs":[],"name":"BurnAmountExceedsBalance","type":"error"},{"inputs":[],"name":"BurnFromNullAddress","type":"error"},{"inputs":[],"name":"DebtLowerThanTheFloor","type":"error"},{"inputs":[],"name":"DebtTokenInactive","type":"error"},{"inputs":[],"name":"FallbackIsNotAllowed","type":"error"},{"inputs":[],"name":"IsShutdown","type":"error"},{"inputs":[],"name":"MintToNullAddress","type":"error"},{"inputs":[],"name":"NameIsNull","type":"error"},{"inputs":[],"name":"NewValueIsSameAsCurrent","type":"error"},{"inputs":[],"name":"NotEnoughCollateral","type":"error"},{"inputs":[],"name":"PoolAddressIsNull","type":"error"},{"inputs":[],"name":"PoolIsNull","type":"error"},{"inputs":[],"name":"ReceiveIsNotAllowed","type":"error"},{"inputs":[],"name":"RemainingDebtIsLowerThanTheFloor","type":"error"},{"inputs":[],"name":"SenderIsNotGovernor","type":"error"},{"inputs":[],"name":"SenderIsNotPool","type":"error"},{"inputs":[],"name":"SenderIsNotSmartFarmingManager","type":"error"},{"inputs":[],"name":"SurpassMaxDebtSupply","type":"error"},{"inputs":[],"name":"SymbolIsNull","type":"error"},{"inputs":[],"name":"SyntheticDoesNotExist","type":"error"},{"inputs":[],"name":"SyntheticIsInactive","type":"error"},{"inputs":[],"name":"SyntheticIsNull","type":"error"},{"inputs":[],"name":"TransferNotSupported","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"payer","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"repaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"DebtRepaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"newActive","type":"bool"}],"name":"DebtTokenActiveUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldInterestRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newInterestRate","type":"uint256"}],"name":"InterestRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMaxTotalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxTotalSupply","type":"uint256"}],"name":"MaxTotalSupplyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"issued","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SyntheticTokenIssued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"SECONDS_PER_YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accrueInterest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectPendingInterestFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"debtIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"flashIssue","outputs":[{"internalType":"uint256","name":"_issued","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"_governor","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"contract IPool","name":"pool_","type":"address"},{"internalType":"contract ISyntheticToken","name":"syntheticToken_","type":"address"},{"internalType":"uint256","name":"interestRate_","type":"uint256"},{"internalType":"uint256","name":"maxTotalSupply_","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"interestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"interestRatePerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"address","name":"to_","type":"address"}],"name":"issue","outputs":[{"internalType":"uint256","name":"_issued","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastTimestampAccrued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingInterestFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"contract IPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToIssue_","type":"uint256"}],"name":"quoteIssueIn","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"quoteIssueOut","outputs":[{"internalType":"uint256","name":"_amountToIssue","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToRepay_","type":"uint256"}],"name":"quoteRepayIn","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"quoteRepayOut","outputs":[{"internalType":"uint256","name":"_amountToRepay","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"onBehalfOf_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"repay","outputs":[{"internalType":"uint256","name":"_repaid","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"onBehalfOf_","type":"address"}],"name":"repayAll","outputs":[{"internalType":"uint256","name":"_repaid","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"syntheticToken","outputs":[{"internalType":"contract ISyntheticToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleIsActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newInterestRate_","type":"uint256"}],"name":"updateInterestRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxTotalSupply_","type":"uint256"}],"name":"updateMaxTotalSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040523480156200001157600080fd5b506200001c62000022565b62000152565b6200002e60ff62000031565b50565b60008054610100900460ff1615620000ca578160ff1660011480156200006a575062000068306200014360201b620029091760201c565b155b620000c25760405162461bcd60e51b815260206004820152602e602482015260008051602062003dfe83398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b506000919050565b60005460ff808416911610620001295760405162461bcd60e51b815260206004820152602e602482015260008051602062003dfe83398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000b9565b506000805460ff191660ff92909216919091179055600190565b6001600160a01b03163b151590565b613c9c80620001626000396000f3fe6080604052600436106102295760003560e01c8063752a50a611610123578063b696a6ad116100ab578063d38f2ba91161006f578063d38f2ba914610672578063d7da606614610692578063dd62ed3e146106a8578063e6a69ab8146106c8578063ffa1ad74146106e057610247565b8063b696a6ad146105e7578063bb8c631f14610607578063bfa176561461061d578063c9dc4b4d1461063d578063d25933291461065d57610247565b806395d89b41116100f257806395d89b411461056d5780639cc820da146105825780639dc29fac14610597578063a6afed95146105b7578063a9059cbb146105cc57610247565b8063752a50a6146104f75780637c27383b146105175780637c3a00fd146105375780638230ecd61461054d57610247565b80632ab4d052116101b15780634754d176116101755780634754d17614610461578063565f3d4f1461048157806362c067671461049757806370a08231146104b757806374e87e1e146104d757610247565b80632ab4d052146103c35780632d4aeea1146103d9578063313ce567146103f957806336248ab41461042c57806340c10f191461044157610247565b8063172f50a4116101f8578063172f50a41461030857806318160ddd1461032a57806322867d781461034d57806322f3e2d41461038257806323b872dd146103a357610247565b806306fdde0314610260578063095ea7b31461028b5780630c340a24146102bb57806316f0115b146102e857610247565b3661024757604051636436c22d60e11b815260040160405180910390fd5b60405163a0152e6360e01b815260040160405180910390fd5b34801561026c57600080fd5b50610275610711565b6040516102829190613685565b60405180910390f35b34801561029757600080fd5b506102ab6102a63660046136cd565b61079f565b6040519015158152602001610282565b3480156102c757600080fd5b506102d06107ba565b6040516001600160a01b039091168152602001610282565b3480156102f457600080fd5b506002546102d0906001600160a01b031681565b34801561031457600080fd5b506103286103233660046136f9565b61083c565b005b34801561033657600080fd5b5061033f6108d8565b604051908152602001610282565b34801561035957600080fd5b5061036d6103683660046136cd565b6108fb565b60408051928352602083019190915201610282565b34801561038e57600080fd5b50603d546102ab90600160a01b900460ff1681565b3480156103af57600080fd5b506102ab6103be366004613712565b610e1c565b3480156103cf57600080fd5b5061033f60385481565b3480156103e557600080fd5b5061036d6103f43660046136f9565b610e37565b34801561040557600080fd5b50603d5461041a90600160a81b900460ff1681565b60405160ff9091168152602001610282565b34801561043857600080fd5b50610328610f70565b34801561044d57600080fd5b5061032861045c3660046136cd565b611059565b34801561046d57600080fd5b5061036d61047c3660046136f9565b6113b7565b34801561048d57600080fd5b5061033f603a5481565b3480156104a357600080fd5b506103286104b2366004613712565b6114de565b3480156104c357600080fd5b5061033f6104d2366004613753565b611517565b3480156104e357600080fd5b506103286104f23660046137b9565b611583565b34801561050357600080fd5b506103286105123660046136f9565b611778565b34801561052357600080fd5b5061036d610532366004613753565b61181c565b34801561054357600080fd5b5061033f603c5481565b34801561055957600080fd5b50603d546102d0906001600160a01b031681565b34801561057957600080fd5b50610275611b9c565b34801561058e57600080fd5b5061033f611ba9565b3480156105a357600080fd5b506103286105b23660046136cd565b611bbd565b3480156105c357600080fd5b50610328611bf6565b3480156105d857600080fd5b506102ab6103be3660046136cd565b3480156105f357600080fd5b5061036d610602366004613860565b611d43565b34801561061357600080fd5b5061033f603b5481565b34801561062957600080fd5b5061036d6106383660046136cd565b612224565b34801561064957600080fd5b5061036d6106583660046136f9565b61260b565b34801561066957600080fd5b5061032861272a565b34801561067e57600080fd5b5061036d61068d3660046136f9565b6127c4565b34801561069e57600080fd5b5061033f603e5481565b3480156106b457600080fd5b5061033f6106c3366004613890565b6128ee565b3480156106d457600080fd5b5061033f6301e187e081565b3480156106ec57600080fd5b50610275604051806040016040528060058152602001640312e332e360dc1b81525081565b6034805461071e906138be565b80601f016020809104026020016040519081016040528092919081815260200182805461074a906138be565b80156107975780601f1061076c57610100808354040283529160200191610797565b820191906000526020600020905b81548152906001019060200180831161077a57829003601f168201915b505050505081565b6000604051631b48e8f360e21b815260040160405180910390fd5b6002546040805163030d028960e21b815290516000926001600160a01b031691630c340a24916004808301926020929190829003018186803b1580156107ff57600080fd5b505afa158015610813573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108379190613904565b905090565b6108446107ba565b6001600160a01b0316336001600160a01b03161461087557604051634b98449160e11b815260040160405180910390fd5b6038548181141561089957604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527fc58cd6132bb46df23d468939c03dd023b74b509aaa6b04c39d5a6461c65963bd910160405180910390a150603855565b6000806108e3612918565b50509050806039546108f59190613937565b91505090565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561094c57600080fd5b505afa158015610960573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610984919061395f565b156109a257604051631b0e923f60e11b815260040160405180910390fd5b600260015414156109ce5760405162461bcd60e51b81526004016109c59061397a565b60405180910390fd5b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b158015610a1a57600080fd5b505afa158015610a2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a52919061395f565b610a6f5760405163a596698b60e01b815260040160405180910390fd5b82610a8d576040516310eb483f60e21b815260040160405180910390fd5b610a95611bf6565b600254603d546001600160a01b039182169116610ab185610e37565b90945092508215610ba557806001600160a01b031663b2a02ff133846001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b0557600080fd5b505afa158015610b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3d9190613904565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101869052606401600060405180830381600087803b158015610b8c57600080fd5b505af1158015610ba0573d6000803e3d6000fd5b505050505b6000826001600160a01b031663f60928096040518163ffffffff1660e01b815260040160206040518083038186803b158015610be057600080fd5b505afa158015610bf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1891906139b1565b90508015610d54576000836001600160a01b031663eaada3826040518163ffffffff1660e01b815260040160206040518083038186803b158015610c5b57600080fd5b505afa158015610c6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c939190613904565b6001600160a01b0316638d0dba008488610cac8c611517565b610cb691906139ca565b6040518363ffffffff1660e01b8152600401610cd39291906139e1565b60206040518083038186803b158015610ceb57600080fd5b505afa158015610cff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2391906139b1565b9050600081118015610d3457508181105b15610d52576040516332b9d47360e01b815260040160405180910390fd5b505b604051632770a7eb60e21b81526001600160a01b03831690639dc29fac90610d8290339089906004016139e1565b600060405180830381600087803b158015610d9c57600080fd5b505af1158015610db0573d6000803e3d6000fd5b50505050610dbe8786612988565b60408051878152602081018790529081018590526001600160a01b0388169033907fe02887340b03318642b6755f258294b795be42ed57d4b5d0ef27be3038d8a7649060600160405180910390a35050600180555090939092509050565b600060405163d21ad44b60e01b815260040160405180910390fd5b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e8a57600080fd5b505afa158015610e9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec29190613904565b6001600160a01b0316637c0f59f46040518163ffffffff1660e01b815260040160206040518083038186803b158015610efa57600080fd5b505afa158015610f0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3291906139b1565b905080610f40575091929050565b610f5c610f5582670de0b6b3a7640000613937565b8590612c03565b9250610f6883856139ca565b915050915091565b603e54801561105657603d54600254604080516331056e5760e21b815290516001600160a01b03938416936340c10f1993169163c415b95c916004808301926020929190829003018186803b158015610fc857600080fd5b505afa158015610fdc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110009190613904565b836040518363ffffffff1660e01b815260040161101e9291906139e1565b600060405180830381600087803b15801561103857600080fd5b505af115801561104c573d6000803e3d6000fd5b50506000603e5550505b50565b600260009054906101000a90046001600160a01b03166001600160a01b03166396aaccfe6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110a757600080fd5b505afa1580156110bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110df9190613904565b6001600160a01b0316336001600160a01b03161461111057604051630935fed760e11b815260040160405180910390fd5b600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561115e57600080fd5b505afa158015611172573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611196919061395f565b156111b457604051631b0e923f60e11b815260040160405180910390fd5b600260015414156111d75760405162461bcd60e51b81526004016109c59061397a565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b15801561122357600080fd5b505afa158015611237573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125b919061395f565b6112785760405163a596698b60e01b815260040160405180910390fd5b603d60009054906101000a90046001600160a01b03166001600160a01b03166322f3e2d46040518163ffffffff1660e01b815260040160206040518083038186803b1580156112c657600080fd5b505afa1580156112da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fe919061395f565b61131b576040516303127d9160e31b815260040160405180910390fd5b611323611bf6565b60025460408051637556d1c160e11b815290516001600160a01b03909216916113ae918391829163eaada382916004808301926020929190829003018186803b15801561136f57600080fd5b505afa158015611383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a79190613904565b8585612c40565b50506001805550565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b15801561140a57600080fd5b505afa15801561141e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114429190613904565b6001600160a01b0316632a9133c16040518163ffffffff1660e01b815260040160206040518083038186803b15801561147a57600080fd5b505afa15801561148e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114b291906139b1565b9050806114c0575091929050565b6114ca848261302c565b91506114d682856139ca565b925050915091565b6114e6613064565b6001600160a01b038316611503576114fe828261309f565b505050565b6114fe6001600160a01b03841683836131b8565b6001600160a01b0381166000908152603660205260408120548061153e5750600092915050565b6000611548612918565b506001600160a01b038616600090815260376020526040902054909250905061157182846139fa565b61157b9190613a19565b949350505050565b600061158f600161320e565b905080156115a7576000805461ff0019166101001790555b876115c557604051636e83f50760e01b815260040160405180910390fd5b856115e3576040516330507cff60e11b815260040160405180910390fd5b6001600160a01b03851661160a57604051633cb1fb1f60e11b815260040160405180910390fd5b6001600160a01b0384166116315760405163013a1b4360e51b815260040160405180910390fd5b61163961329b565b611642856132ca565b61164e60348a8a6135bc565b5061165b603588886135bc565b50836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561169557600080fd5b505afa1580156116a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cd9190613a3b565b603d805442603a55670de0b6b3a7640000603b55603c86905560388590556001600160a81b031960ff93909316600160a81b02929092166001600160b01b0319909216919091176001600160a01b03861617600160a01b179055801561176d576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050505050565b6117806107ba565b6001600160a01b0316336001600160a01b0316146117b157604051634b98449160e11b815260040160405180910390fd5b6117b9611bf6565b603c54818114156117dd57604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527f41e376fd99913dea7fda140f5c0bd997515b1a181acc58737320322548ec6e72910160405180910390a150603c55565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561186d57600080fd5b505afa158015611881573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a5919061395f565b156118c357604051631b0e923f60e11b815260040160405180910390fd5b600260015414156118e65760405162461bcd60e51b81526004016109c59061397a565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b15801561193257600080fd5b505afa158015611946573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196a919061395f565b6119875760405163a596698b60e01b815260040160405180910390fd5b61198f611bf6565b61199883611517565b9150816119b8576040516310eb483f60e21b815260040160405180910390fd5b603d546001600160a01b031660006119cf8461260b565b935090508215611ad757816001600160a01b031663b2a02ff133600260009054906101000a90046001600160a01b03166001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3757600080fd5b505afa158015611a4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6f9190613904565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101869052606401600060405180830381600087803b158015611abe57600080fd5b505af1158015611ad2573d6000803e3d6000fd5b505050505b604051632770a7eb60e21b81526001600160a01b03831690639dc29fac90611b0590339088906004016139e1565b600060405180830381600087803b158015611b1f57600080fd5b505af1158015611b33573d6000803e3d6000fd5b50505050611b418585612988565b60408051828152602081018690529081018490526001600160a01b0386169033907fe02887340b03318642b6755f258294b795be42ed57d4b5d0ef27be3038d8a7649060600160405180910390a35050600180559092909150565b6035805461071e906138be565b60006301e187e0603c546108379190613a19565b6002546001600160a01b03163314611be85760405163531f2aa960e11b815260040160405180910390fd5b611bf28282612988565b5050565b6000806000611c03612918565b92509250925080421415611c1657505050565b42603a5582156114fe578260396000828254611c329190613937565b9091555050603b829055603d54600254604080516331056e5760e21b815290516001600160a01b03938416936340c10f1993169163c415b95c916004808301926020929190829003018186803b158015611c8b57600080fd5b505afa158015611c9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc39190613904565b603e54611cd09087613937565b6040518363ffffffff1660e01b8152600401611ced9291906139e1565b600060405180830381600087803b158015611d0757600080fd5b505af1925050508015611d18575060015b611d395782603e6000828254611d2e9190613937565b909155506114fe9050565b6000603e55505050565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b158015611d9457600080fd5b505afa158015611da8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dcc919061395f565b15611dea57604051631b0e923f60e11b815260040160405180910390fd5b60026001541415611e0d5760405162461bcd60e51b81526004016109c59061397a565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b158015611e5957600080fd5b505afa158015611e6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e91919061395f565b611eae5760405163a596698b60e01b815260040160405180910390fd5b83611ecc576040516310eb483f60e21b815260040160405180910390fd5b611ed4611bf6565b600254603d5460405163dde3ab9560e01b81523360048201526001600160a01b039283169290911690600090839063dde3ab959060240160a06040518083038186803b158015611f2357600080fd5b505afa158015611f37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5b9190613a5e565b9450505050506000836001600160a01b031663eaada3826040518163ffffffff1660e01b815260040160206040518083038186803b158015611f9c57600080fd5b505afa158015611fb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd49190613904565b60405163b5e9bef560e01b81529091506001600160a01b0382169063b5e9bef59061200590869086906004016139e1565b60206040518083038186803b15801561201d57600080fd5b505afa158015612031573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205591906139b1565b8811156120745760405162d11df360e61b815260040160405180910390fd5b6120808482338b612c40565b612089886113b7565b9096509450841561216557826001600160a01b03166340c10f19856001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156120dc57600080fd5b505afa1580156120f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121149190613904565b876040518363ffffffff1660e01b81526004016121329291906139e1565b600060405180830381600087803b15801561214c57600080fd5b505af1158015612160573d6000803e3d6000fd5b505050505b6040516340c10f1960e01b81526001600160a01b038416906340c10f1990612193908a908a906004016139e1565b600060405180830381600087803b1580156121ad57600080fd5b505af11580156121c1573d6000803e3d6000fd5b5050604080518b8152602081018a90529081018890526001600160a01b038a1692503391507f197d5e1e72d62df9dad3add8609553402104dbeb4f83f9789e33aeb6723a78399060600160405180910390a3505060018055509194909350915050565b600080600260009054906101000a90046001600160a01b03166001600160a01b03166396aaccfe6040518163ffffffff1660e01b815260040160206040518083038186803b15801561227557600080fd5b505afa158015612289573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ad9190613904565b6001600160a01b0316336001600160a01b0316146122de57604051630935fed760e11b815260040160405180910390fd5b600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561232c57600080fd5b505afa158015612340573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612364919061395f565b1561238257604051631b0e923f60e11b815260040160405180910390fd5b600260015414156123a55760405162461bcd60e51b81526004016109c59061397a565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b1580156123f157600080fd5b505afa158015612405573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612429919061395f565b6124465760405163a596698b60e01b815260040160405180910390fd5b603d54600160a01b900460ff166124705760405163a4382ae360e01b815260040160405180910390fd5b8261248e576040516310eb483f60e21b815260040160405180910390fd5b612496611bf6565b603d546001600160a01b03166124ab846113b7565b9093509150811561259c57806001600160a01b03166340c10f19600260009054906101000a90046001600160a01b03166001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561251357600080fd5b505afa158015612527573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254b9190613904565b846040518363ffffffff1660e01b81526004016125699291906139e1565b600060405180830381600087803b15801561258357600080fd5b505af1158015612597573d6000803e3d6000fd5b505050505b6040516340c10f1960e01b81526001600160a01b038216906340c10f19906125ca90889087906004016139e1565b600060405180830381600087803b1580156125e457600080fd5b505af11580156125f8573d6000803e3d6000fd5b5050505050600180819055509250929050565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b15801561265e57600080fd5b505afa158015612672573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126969190613904565b6001600160a01b0316637c0f59f46040518163ffffffff1660e01b815260040160206040518083038186803b1580156126ce57600080fd5b505afa1580156126e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270691906139b1565b905080612714575091929050565b61271e848261302c565b91506114d68285613937565b6127326107ba565b6001600160a01b0316336001600160a01b03161461276357604051634b98449160e11b815260040160405180910390fd5b603d54604051600160a01b90910460ff1615808252907fb1d9ceb4467fd05a16930f966760d70eb5926cf0c1c19a7b6bfe59d805c190459060200160405180910390a1603d8054911515600160a01b0260ff60a01b19909216919091179055565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b15801561281757600080fd5b505afa15801561282b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284f9190613904565b6001600160a01b0316632a9133c16040518163ffffffff1660e01b815260040160206040518083038186803b15801561288757600080fd5b505afa15801561289b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128bf91906139b1565b9050806128cd575091929050565b6128e2610f5582670de0b6b3a76400006139ca565b9250610f6884846139ca565b600060405163effde13d60e01b815260040160405180910390fd5b6001600160a01b03163b151590565b603a54603b546000914281101561298357600061293582426139ca565b61293d611ba9565b61294791906139fa565b905080156129815760395461295d90829061302c565b9350612974603b548261302c90919063ffffffff16565b61297e9084613937565b92505b505b909192565b816000600260009054906101000a90046001600160a01b03166001600160a01b0316633605b51b6040518163ffffffff1660e01b815260040160006040518083038186803b1580156129d957600080fd5b505afa1580156129ed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a159190810190613abb565b603d5481519192506001600160a01b03169060005b81811015612ac357838181518110612a4457612a44613b80565b6020908102919091010151604051626cc3c360e61b81526001600160a01b038581166004830152878116602483015290911690631b30f0c090604401600060405180830381600087803b158015612a9a57600080fd5b505af1158015612aae573d6000803e3d6000fd5b5050505080612abc90613b96565b9050612a2a565b506001600160a01b038616612aeb5760405163170476af60e21b815260040160405180910390fd5b6000612af687611517565b905085811015612b1957604051630bba337f60e11b815260040160405180910390fd5b6001600160a01b03871660008181526036602090815260408083208a86039055603b546037835281842055603980548b90039055518981529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3600086118015612b955750612b9387611517565b155b15612bfa57600254604051631d71be3b60e21b81526001600160a01b038981166004830152909116906375c6f8ec90602401600060405180830381600087803b158015612be157600080fd5b505af1158015612bf5573d6000803e3d6000fd5b505050505b50505050505050565b600081612c11600282613a19565b612c23670de0b6b3a7640000866139fa565b612c2d9190613937565b612c379190613a19565b90505b92915050565b603d54600160a01b900460ff16612c6a5760405163a4382ae360e01b815260040160405180910390fd5b816000600260009054906101000a90046001600160a01b03166001600160a01b0316633605b51b6040518163ffffffff1660e01b815260040160006040518083038186803b158015612cbb57600080fd5b505afa158015612ccf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612cf79190810190613abb565b603d5481519192506001600160a01b03169060005b81811015612da557838181518110612d2657612d26613b80565b6020908102919091010151604051626cc3c360e61b81526001600160a01b038581166004830152878116602483015290911690631b30f0c090604401600060405180830381600087803b158015612d7c57600080fd5b505af1158015612d90573d6000803e3d6000fd5b5050505080612d9e90613b96565b9050612d0c565b506001600160a01b038616612dcd57604051632b61339160e21b815260040160405180910390fd5b6000886001600160a01b031663f60928096040518163ffffffff1660e01b815260040160206040518083038186803b158015612e0857600080fd5b505afa158015612e1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4091906139b1565b90506000612e4d88611517565b9050600082118015612eeb5750603d5482906001600160a01b03808c1691638d0dba009116612e7c8b86613937565b6040518363ffffffff1660e01b8152600401612e999291906139e1565b60206040518083038186803b158015612eb157600080fd5b505afa158015612ec5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ee991906139b1565b105b15612f0957604051637e76d52960e11b815260040160405180910390fd5b8660396000828254612f1b9190613937565b90915550506038546039541115612f4557604051634aed251160e11b815260040160405180910390fd5b612f4f8782613937565b6001600160a01b038916600081815260366020908152604080832094909455603b54603782528483205592518a8152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a380158015612fbb5750600087115b1561302057600254604051631dc2da6d60e21b81526001600160a01b038a811660048301529091169063770b69b490602401600060405180830381600087803b15801561300757600080fd5b505af115801561301b573d6000803e3d6000fd5b505050505b50505050505050505050565b6000821580613039575081155b1561304657506000612c3a565b670de0b6b3a764000061305a600282613a19565b612c2384866139fa565b61306c6107ba565b6001600160a01b0316336001600160a01b03161461309d57604051634b98449160e11b815260040160405180910390fd5b565b804710156130ef5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016109c5565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461313c576040519150601f19603f3d011682016040523d82523d6000602084013e613141565b606091505b50509050806114fe5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016109c5565b6114fe8363a9059cbb60e01b84846040516024016131d79291906139e1565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261333a565b60008054610100900460ff1615613255578160ff1660011480156132315750303b155b61324d5760405162461bcd60e51b81526004016109c590613bb1565b506000919050565b60005460ff80841691161061327c5760405162461bcd60e51b81526004016109c590613bb1565b506000805460ff191660ff92909216919091179055600190565b919050565b600054610100900460ff166132c25760405162461bcd60e51b81526004016109c590613bff565b61309d61340c565b600054610100900460ff166132f15760405162461bcd60e51b81526004016109c590613bff565b6001600160a01b0381166133185760405163724f500960e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b600061338f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134399092919063ffffffff16565b8051909150156114fe57808060200190518101906133ad919061395f565b6114fe5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109c5565b600054610100900460ff166134335760405162461bcd60e51b81526004016109c590613bff565b60018055565b60606134488484600085613452565b90505b9392505050565b6060824710156134b35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109c5565b6001600160a01b0385163b61350a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109c5565b600080866001600160a01b031685876040516135269190613c4a565b60006040518083038185875af1925050503d8060008114613563576040519150601f19603f3d011682016040523d82523d6000602084013e613568565b606091505b5091509150613578828286613583565b979650505050505050565b6060831561359257508161344b565b8251156135a25782518084602001fd5b8160405162461bcd60e51b81526004016109c59190613685565b8280546135c8906138be565b90600052602060002090601f0160209004810192826135ea5760008555613630565b82601f106136035782800160ff19823516178555613630565b82800160010185558215613630579182015b82811115613630578235825591602001919060010190613615565b5061363c929150613640565b5090565b5b8082111561363c5760008155600101613641565b60005b83811015613670578181015183820152602001613658565b8381111561367f576000848401525b50505050565b60208152600082518060208401526136a4816040850160208701613655565b601f01601f19169190910160400192915050565b6001600160a01b038116811461105657600080fd5b600080604083850312156136e057600080fd5b82356136eb816136b8565b946020939093013593505050565b60006020828403121561370b57600080fd5b5035919050565b60008060006060848603121561372757600080fd5b8335613732816136b8565b92506020840135613742816136b8565b929592945050506040919091013590565b60006020828403121561376557600080fd5b813561344b816136b8565b60008083601f84011261378257600080fd5b50813567ffffffffffffffff81111561379a57600080fd5b6020830191508360208285010111156137b257600080fd5b9250929050565b60008060008060008060008060c0898b0312156137d557600080fd5b883567ffffffffffffffff808211156137ed57600080fd5b6137f98c838d01613770565b909a50985060208b013591508082111561381257600080fd5b5061381f8b828c01613770565b9097509550506040890135613833816136b8565b93506060890135613843816136b8565b979a969950949793969295929450505060808201359160a0013590565b6000806040838503121561387357600080fd5b823591506020830135613885816136b8565b809150509250929050565b600080604083850312156138a357600080fd5b82356138ae816136b8565b91506020830135613885816136b8565b600181811c908216806138d257607f821691505b602082108114156138f357634e487b7160e01b600052602260045260246000fd5b50919050565b8051613296816136b8565b60006020828403121561391657600080fd5b815161344b816136b8565b634e487b7160e01b600052601160045260246000fd5b6000821982111561394a5761394a613921565b500190565b8051801515811461329657600080fd5b60006020828403121561397157600080fd5b612c378261394f565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000602082840312156139c357600080fd5b5051919050565b6000828210156139dc576139dc613921565b500390565b6001600160a01b03929092168252602082015260400190565b6000816000190483118215151615613a1457613a14613921565b500290565b600082613a3657634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215613a4d57600080fd5b815160ff8116811461344b57600080fd5b600080600080600060a08688031215613a7657600080fd5b613a7f8661394f565b602087015160408801516060890151608090990151929a91995097965090945092505050565b634e487b7160e01b600052604160045260246000fd5b60006020808385031215613ace57600080fd5b825167ffffffffffffffff80821115613ae657600080fd5b818501915085601f830112613afa57600080fd5b815181811115613b0c57613b0c613aa5565b8060051b604051601f19603f83011681018181108582111715613b3157613b31613aa5565b604052918252848201925083810185019188831115613b4f57600080fd5b938501935b82851015613b7457613b65856138f9565b84529385019392850192613b54565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b6000600019821415613baa57613baa613921565b5060010190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008251613c5c818460208701613655565b919091019291505056fea26469706673582212202a942e4446d0845826179dd94c6f9bde886db2b71bc4497729679f81e179a56a64736f6c63430008090033496e697469616c697a61626c653a20636f6e747261637420697320616c726561
Deployed Bytecode
0x6080604052600436106102295760003560e01c8063752a50a611610123578063b696a6ad116100ab578063d38f2ba91161006f578063d38f2ba914610672578063d7da606614610692578063dd62ed3e146106a8578063e6a69ab8146106c8578063ffa1ad74146106e057610247565b8063b696a6ad146105e7578063bb8c631f14610607578063bfa176561461061d578063c9dc4b4d1461063d578063d25933291461065d57610247565b806395d89b41116100f257806395d89b411461056d5780639cc820da146105825780639dc29fac14610597578063a6afed95146105b7578063a9059cbb146105cc57610247565b8063752a50a6146104f75780637c27383b146105175780637c3a00fd146105375780638230ecd61461054d57610247565b80632ab4d052116101b15780634754d176116101755780634754d17614610461578063565f3d4f1461048157806362c067671461049757806370a08231146104b757806374e87e1e146104d757610247565b80632ab4d052146103c35780632d4aeea1146103d9578063313ce567146103f957806336248ab41461042c57806340c10f191461044157610247565b8063172f50a4116101f8578063172f50a41461030857806318160ddd1461032a57806322867d781461034d57806322f3e2d41461038257806323b872dd146103a357610247565b806306fdde0314610260578063095ea7b31461028b5780630c340a24146102bb57806316f0115b146102e857610247565b3661024757604051636436c22d60e11b815260040160405180910390fd5b60405163a0152e6360e01b815260040160405180910390fd5b34801561026c57600080fd5b50610275610711565b6040516102829190613685565b60405180910390f35b34801561029757600080fd5b506102ab6102a63660046136cd565b61079f565b6040519015158152602001610282565b3480156102c757600080fd5b506102d06107ba565b6040516001600160a01b039091168152602001610282565b3480156102f457600080fd5b506002546102d0906001600160a01b031681565b34801561031457600080fd5b506103286103233660046136f9565b61083c565b005b34801561033657600080fd5b5061033f6108d8565b604051908152602001610282565b34801561035957600080fd5b5061036d6103683660046136cd565b6108fb565b60408051928352602083019190915201610282565b34801561038e57600080fd5b50603d546102ab90600160a01b900460ff1681565b3480156103af57600080fd5b506102ab6103be366004613712565b610e1c565b3480156103cf57600080fd5b5061033f60385481565b3480156103e557600080fd5b5061036d6103f43660046136f9565b610e37565b34801561040557600080fd5b50603d5461041a90600160a81b900460ff1681565b60405160ff9091168152602001610282565b34801561043857600080fd5b50610328610f70565b34801561044d57600080fd5b5061032861045c3660046136cd565b611059565b34801561046d57600080fd5b5061036d61047c3660046136f9565b6113b7565b34801561048d57600080fd5b5061033f603a5481565b3480156104a357600080fd5b506103286104b2366004613712565b6114de565b3480156104c357600080fd5b5061033f6104d2366004613753565b611517565b3480156104e357600080fd5b506103286104f23660046137b9565b611583565b34801561050357600080fd5b506103286105123660046136f9565b611778565b34801561052357600080fd5b5061036d610532366004613753565b61181c565b34801561054357600080fd5b5061033f603c5481565b34801561055957600080fd5b50603d546102d0906001600160a01b031681565b34801561057957600080fd5b50610275611b9c565b34801561058e57600080fd5b5061033f611ba9565b3480156105a357600080fd5b506103286105b23660046136cd565b611bbd565b3480156105c357600080fd5b50610328611bf6565b3480156105d857600080fd5b506102ab6103be3660046136cd565b3480156105f357600080fd5b5061036d610602366004613860565b611d43565b34801561061357600080fd5b5061033f603b5481565b34801561062957600080fd5b5061036d6106383660046136cd565b612224565b34801561064957600080fd5b5061036d6106583660046136f9565b61260b565b34801561066957600080fd5b5061032861272a565b34801561067e57600080fd5b5061036d61068d3660046136f9565b6127c4565b34801561069e57600080fd5b5061033f603e5481565b3480156106b457600080fd5b5061033f6106c3366004613890565b6128ee565b3480156106d457600080fd5b5061033f6301e187e081565b3480156106ec57600080fd5b50610275604051806040016040528060058152602001640312e332e360dc1b81525081565b6034805461071e906138be565b80601f016020809104026020016040519081016040528092919081815260200182805461074a906138be565b80156107975780601f1061076c57610100808354040283529160200191610797565b820191906000526020600020905b81548152906001019060200180831161077a57829003601f168201915b505050505081565b6000604051631b48e8f360e21b815260040160405180910390fd5b6002546040805163030d028960e21b815290516000926001600160a01b031691630c340a24916004808301926020929190829003018186803b1580156107ff57600080fd5b505afa158015610813573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108379190613904565b905090565b6108446107ba565b6001600160a01b0316336001600160a01b03161461087557604051634b98449160e11b815260040160405180910390fd5b6038548181141561089957604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527fc58cd6132bb46df23d468939c03dd023b74b509aaa6b04c39d5a6461c65963bd910160405180910390a150603855565b6000806108e3612918565b50509050806039546108f59190613937565b91505090565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561094c57600080fd5b505afa158015610960573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610984919061395f565b156109a257604051631b0e923f60e11b815260040160405180910390fd5b600260015414156109ce5760405162461bcd60e51b81526004016109c59061397a565b60405180910390fd5b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b158015610a1a57600080fd5b505afa158015610a2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a52919061395f565b610a6f5760405163a596698b60e01b815260040160405180910390fd5b82610a8d576040516310eb483f60e21b815260040160405180910390fd5b610a95611bf6565b600254603d546001600160a01b039182169116610ab185610e37565b90945092508215610ba557806001600160a01b031663b2a02ff133846001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b0557600080fd5b505afa158015610b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3d9190613904565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101869052606401600060405180830381600087803b158015610b8c57600080fd5b505af1158015610ba0573d6000803e3d6000fd5b505050505b6000826001600160a01b031663f60928096040518163ffffffff1660e01b815260040160206040518083038186803b158015610be057600080fd5b505afa158015610bf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1891906139b1565b90508015610d54576000836001600160a01b031663eaada3826040518163ffffffff1660e01b815260040160206040518083038186803b158015610c5b57600080fd5b505afa158015610c6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c939190613904565b6001600160a01b0316638d0dba008488610cac8c611517565b610cb691906139ca565b6040518363ffffffff1660e01b8152600401610cd39291906139e1565b60206040518083038186803b158015610ceb57600080fd5b505afa158015610cff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2391906139b1565b9050600081118015610d3457508181105b15610d52576040516332b9d47360e01b815260040160405180910390fd5b505b604051632770a7eb60e21b81526001600160a01b03831690639dc29fac90610d8290339089906004016139e1565b600060405180830381600087803b158015610d9c57600080fd5b505af1158015610db0573d6000803e3d6000fd5b50505050610dbe8786612988565b60408051878152602081018790529081018590526001600160a01b0388169033907fe02887340b03318642b6755f258294b795be42ed57d4b5d0ef27be3038d8a7649060600160405180910390a35050600180555090939092509050565b600060405163d21ad44b60e01b815260040160405180910390fd5b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e8a57600080fd5b505afa158015610e9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec29190613904565b6001600160a01b0316637c0f59f46040518163ffffffff1660e01b815260040160206040518083038186803b158015610efa57600080fd5b505afa158015610f0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3291906139b1565b905080610f40575091929050565b610f5c610f5582670de0b6b3a7640000613937565b8590612c03565b9250610f6883856139ca565b915050915091565b603e54801561105657603d54600254604080516331056e5760e21b815290516001600160a01b03938416936340c10f1993169163c415b95c916004808301926020929190829003018186803b158015610fc857600080fd5b505afa158015610fdc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110009190613904565b836040518363ffffffff1660e01b815260040161101e9291906139e1565b600060405180830381600087803b15801561103857600080fd5b505af115801561104c573d6000803e3d6000fd5b50506000603e5550505b50565b600260009054906101000a90046001600160a01b03166001600160a01b03166396aaccfe6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110a757600080fd5b505afa1580156110bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110df9190613904565b6001600160a01b0316336001600160a01b03161461111057604051630935fed760e11b815260040160405180910390fd5b600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561115e57600080fd5b505afa158015611172573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611196919061395f565b156111b457604051631b0e923f60e11b815260040160405180910390fd5b600260015414156111d75760405162461bcd60e51b81526004016109c59061397a565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b15801561122357600080fd5b505afa158015611237573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125b919061395f565b6112785760405163a596698b60e01b815260040160405180910390fd5b603d60009054906101000a90046001600160a01b03166001600160a01b03166322f3e2d46040518163ffffffff1660e01b815260040160206040518083038186803b1580156112c657600080fd5b505afa1580156112da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fe919061395f565b61131b576040516303127d9160e31b815260040160405180910390fd5b611323611bf6565b60025460408051637556d1c160e11b815290516001600160a01b03909216916113ae918391829163eaada382916004808301926020929190829003018186803b15801561136f57600080fd5b505afa158015611383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a79190613904565b8585612c40565b50506001805550565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b15801561140a57600080fd5b505afa15801561141e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114429190613904565b6001600160a01b0316632a9133c16040518163ffffffff1660e01b815260040160206040518083038186803b15801561147a57600080fd5b505afa15801561148e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114b291906139b1565b9050806114c0575091929050565b6114ca848261302c565b91506114d682856139ca565b925050915091565b6114e6613064565b6001600160a01b038316611503576114fe828261309f565b505050565b6114fe6001600160a01b03841683836131b8565b6001600160a01b0381166000908152603660205260408120548061153e5750600092915050565b6000611548612918565b506001600160a01b038616600090815260376020526040902054909250905061157182846139fa565b61157b9190613a19565b949350505050565b600061158f600161320e565b905080156115a7576000805461ff0019166101001790555b876115c557604051636e83f50760e01b815260040160405180910390fd5b856115e3576040516330507cff60e11b815260040160405180910390fd5b6001600160a01b03851661160a57604051633cb1fb1f60e11b815260040160405180910390fd5b6001600160a01b0384166116315760405163013a1b4360e51b815260040160405180910390fd5b61163961329b565b611642856132ca565b61164e60348a8a6135bc565b5061165b603588886135bc565b50836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561169557600080fd5b505afa1580156116a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cd9190613a3b565b603d805442603a55670de0b6b3a7640000603b55603c86905560388590556001600160a81b031960ff93909316600160a81b02929092166001600160b01b0319909216919091176001600160a01b03861617600160a01b179055801561176d576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050505050565b6117806107ba565b6001600160a01b0316336001600160a01b0316146117b157604051634b98449160e11b815260040160405180910390fd5b6117b9611bf6565b603c54818114156117dd57604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527f41e376fd99913dea7fda140f5c0bd997515b1a181acc58737320322548ec6e72910160405180910390a150603c55565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561186d57600080fd5b505afa158015611881573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a5919061395f565b156118c357604051631b0e923f60e11b815260040160405180910390fd5b600260015414156118e65760405162461bcd60e51b81526004016109c59061397a565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b15801561193257600080fd5b505afa158015611946573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196a919061395f565b6119875760405163a596698b60e01b815260040160405180910390fd5b61198f611bf6565b61199883611517565b9150816119b8576040516310eb483f60e21b815260040160405180910390fd5b603d546001600160a01b031660006119cf8461260b565b935090508215611ad757816001600160a01b031663b2a02ff133600260009054906101000a90046001600160a01b03166001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3757600080fd5b505afa158015611a4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6f9190613904565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101869052606401600060405180830381600087803b158015611abe57600080fd5b505af1158015611ad2573d6000803e3d6000fd5b505050505b604051632770a7eb60e21b81526001600160a01b03831690639dc29fac90611b0590339088906004016139e1565b600060405180830381600087803b158015611b1f57600080fd5b505af1158015611b33573d6000803e3d6000fd5b50505050611b418585612988565b60408051828152602081018690529081018490526001600160a01b0386169033907fe02887340b03318642b6755f258294b795be42ed57d4b5d0ef27be3038d8a7649060600160405180910390a35050600180559092909150565b6035805461071e906138be565b60006301e187e0603c546108379190613a19565b6002546001600160a01b03163314611be85760405163531f2aa960e11b815260040160405180910390fd5b611bf28282612988565b5050565b6000806000611c03612918565b92509250925080421415611c1657505050565b42603a5582156114fe578260396000828254611c329190613937565b9091555050603b829055603d54600254604080516331056e5760e21b815290516001600160a01b03938416936340c10f1993169163c415b95c916004808301926020929190829003018186803b158015611c8b57600080fd5b505afa158015611c9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc39190613904565b603e54611cd09087613937565b6040518363ffffffff1660e01b8152600401611ced9291906139e1565b600060405180830381600087803b158015611d0757600080fd5b505af1925050508015611d18575060015b611d395782603e6000828254611d2e9190613937565b909155506114fe9050565b6000603e55505050565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b158015611d9457600080fd5b505afa158015611da8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dcc919061395f565b15611dea57604051631b0e923f60e11b815260040160405180910390fd5b60026001541415611e0d5760405162461bcd60e51b81526004016109c59061397a565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b158015611e5957600080fd5b505afa158015611e6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e91919061395f565b611eae5760405163a596698b60e01b815260040160405180910390fd5b83611ecc576040516310eb483f60e21b815260040160405180910390fd5b611ed4611bf6565b600254603d5460405163dde3ab9560e01b81523360048201526001600160a01b039283169290911690600090839063dde3ab959060240160a06040518083038186803b158015611f2357600080fd5b505afa158015611f37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5b9190613a5e565b9450505050506000836001600160a01b031663eaada3826040518163ffffffff1660e01b815260040160206040518083038186803b158015611f9c57600080fd5b505afa158015611fb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd49190613904565b60405163b5e9bef560e01b81529091506001600160a01b0382169063b5e9bef59061200590869086906004016139e1565b60206040518083038186803b15801561201d57600080fd5b505afa158015612031573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205591906139b1565b8811156120745760405162d11df360e61b815260040160405180910390fd5b6120808482338b612c40565b612089886113b7565b9096509450841561216557826001600160a01b03166340c10f19856001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156120dc57600080fd5b505afa1580156120f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121149190613904565b876040518363ffffffff1660e01b81526004016121329291906139e1565b600060405180830381600087803b15801561214c57600080fd5b505af1158015612160573d6000803e3d6000fd5b505050505b6040516340c10f1960e01b81526001600160a01b038416906340c10f1990612193908a908a906004016139e1565b600060405180830381600087803b1580156121ad57600080fd5b505af11580156121c1573d6000803e3d6000fd5b5050604080518b8152602081018a90529081018890526001600160a01b038a1692503391507f197d5e1e72d62df9dad3add8609553402104dbeb4f83f9789e33aeb6723a78399060600160405180910390a3505060018055509194909350915050565b600080600260009054906101000a90046001600160a01b03166001600160a01b03166396aaccfe6040518163ffffffff1660e01b815260040160206040518083038186803b15801561227557600080fd5b505afa158015612289573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ad9190613904565b6001600160a01b0316336001600160a01b0316146122de57604051630935fed760e11b815260040160405180910390fd5b600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561232c57600080fd5b505afa158015612340573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612364919061395f565b1561238257604051631b0e923f60e11b815260040160405180910390fd5b600260015414156123a55760405162461bcd60e51b81526004016109c59061397a565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b1580156123f157600080fd5b505afa158015612405573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612429919061395f565b6124465760405163a596698b60e01b815260040160405180910390fd5b603d54600160a01b900460ff166124705760405163a4382ae360e01b815260040160405180910390fd5b8261248e576040516310eb483f60e21b815260040160405180910390fd5b612496611bf6565b603d546001600160a01b03166124ab846113b7565b9093509150811561259c57806001600160a01b03166340c10f19600260009054906101000a90046001600160a01b03166001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561251357600080fd5b505afa158015612527573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254b9190613904565b846040518363ffffffff1660e01b81526004016125699291906139e1565b600060405180830381600087803b15801561258357600080fd5b505af1158015612597573d6000803e3d6000fd5b505050505b6040516340c10f1960e01b81526001600160a01b038216906340c10f19906125ca90889087906004016139e1565b600060405180830381600087803b1580156125e457600080fd5b505af11580156125f8573d6000803e3d6000fd5b5050505050600180819055509250929050565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b15801561265e57600080fd5b505afa158015612672573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126969190613904565b6001600160a01b0316637c0f59f46040518163ffffffff1660e01b815260040160206040518083038186803b1580156126ce57600080fd5b505afa1580156126e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270691906139b1565b905080612714575091929050565b61271e848261302c565b91506114d68285613937565b6127326107ba565b6001600160a01b0316336001600160a01b03161461276357604051634b98449160e11b815260040160405180910390fd5b603d54604051600160a01b90910460ff1615808252907fb1d9ceb4467fd05a16930f966760d70eb5926cf0c1c19a7b6bfe59d805c190459060200160405180910390a1603d8054911515600160a01b0260ff60a01b19909216919091179055565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b15801561281757600080fd5b505afa15801561282b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284f9190613904565b6001600160a01b0316632a9133c16040518163ffffffff1660e01b815260040160206040518083038186803b15801561288757600080fd5b505afa15801561289b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128bf91906139b1565b9050806128cd575091929050565b6128e2610f5582670de0b6b3a76400006139ca565b9250610f6884846139ca565b600060405163effde13d60e01b815260040160405180910390fd5b6001600160a01b03163b151590565b603a54603b546000914281101561298357600061293582426139ca565b61293d611ba9565b61294791906139fa565b905080156129815760395461295d90829061302c565b9350612974603b548261302c90919063ffffffff16565b61297e9084613937565b92505b505b909192565b816000600260009054906101000a90046001600160a01b03166001600160a01b0316633605b51b6040518163ffffffff1660e01b815260040160006040518083038186803b1580156129d957600080fd5b505afa1580156129ed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a159190810190613abb565b603d5481519192506001600160a01b03169060005b81811015612ac357838181518110612a4457612a44613b80565b6020908102919091010151604051626cc3c360e61b81526001600160a01b038581166004830152878116602483015290911690631b30f0c090604401600060405180830381600087803b158015612a9a57600080fd5b505af1158015612aae573d6000803e3d6000fd5b5050505080612abc90613b96565b9050612a2a565b506001600160a01b038616612aeb5760405163170476af60e21b815260040160405180910390fd5b6000612af687611517565b905085811015612b1957604051630bba337f60e11b815260040160405180910390fd5b6001600160a01b03871660008181526036602090815260408083208a86039055603b546037835281842055603980548b90039055518981529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3600086118015612b955750612b9387611517565b155b15612bfa57600254604051631d71be3b60e21b81526001600160a01b038981166004830152909116906375c6f8ec90602401600060405180830381600087803b158015612be157600080fd5b505af1158015612bf5573d6000803e3d6000fd5b505050505b50505050505050565b600081612c11600282613a19565b612c23670de0b6b3a7640000866139fa565b612c2d9190613937565b612c379190613a19565b90505b92915050565b603d54600160a01b900460ff16612c6a5760405163a4382ae360e01b815260040160405180910390fd5b816000600260009054906101000a90046001600160a01b03166001600160a01b0316633605b51b6040518163ffffffff1660e01b815260040160006040518083038186803b158015612cbb57600080fd5b505afa158015612ccf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612cf79190810190613abb565b603d5481519192506001600160a01b03169060005b81811015612da557838181518110612d2657612d26613b80565b6020908102919091010151604051626cc3c360e61b81526001600160a01b038581166004830152878116602483015290911690631b30f0c090604401600060405180830381600087803b158015612d7c57600080fd5b505af1158015612d90573d6000803e3d6000fd5b5050505080612d9e90613b96565b9050612d0c565b506001600160a01b038616612dcd57604051632b61339160e21b815260040160405180910390fd5b6000886001600160a01b031663f60928096040518163ffffffff1660e01b815260040160206040518083038186803b158015612e0857600080fd5b505afa158015612e1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4091906139b1565b90506000612e4d88611517565b9050600082118015612eeb5750603d5482906001600160a01b03808c1691638d0dba009116612e7c8b86613937565b6040518363ffffffff1660e01b8152600401612e999291906139e1565b60206040518083038186803b158015612eb157600080fd5b505afa158015612ec5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ee991906139b1565b105b15612f0957604051637e76d52960e11b815260040160405180910390fd5b8660396000828254612f1b9190613937565b90915550506038546039541115612f4557604051634aed251160e11b815260040160405180910390fd5b612f4f8782613937565b6001600160a01b038916600081815260366020908152604080832094909455603b54603782528483205592518a8152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a380158015612fbb5750600087115b1561302057600254604051631dc2da6d60e21b81526001600160a01b038a811660048301529091169063770b69b490602401600060405180830381600087803b15801561300757600080fd5b505af115801561301b573d6000803e3d6000fd5b505050505b50505050505050505050565b6000821580613039575081155b1561304657506000612c3a565b670de0b6b3a764000061305a600282613a19565b612c2384866139fa565b61306c6107ba565b6001600160a01b0316336001600160a01b03161461309d57604051634b98449160e11b815260040160405180910390fd5b565b804710156130ef5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016109c5565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461313c576040519150601f19603f3d011682016040523d82523d6000602084013e613141565b606091505b50509050806114fe5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016109c5565b6114fe8363a9059cbb60e01b84846040516024016131d79291906139e1565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261333a565b60008054610100900460ff1615613255578160ff1660011480156132315750303b155b61324d5760405162461bcd60e51b81526004016109c590613bb1565b506000919050565b60005460ff80841691161061327c5760405162461bcd60e51b81526004016109c590613bb1565b506000805460ff191660ff92909216919091179055600190565b919050565b600054610100900460ff166132c25760405162461bcd60e51b81526004016109c590613bff565b61309d61340c565b600054610100900460ff166132f15760405162461bcd60e51b81526004016109c590613bff565b6001600160a01b0381166133185760405163724f500960e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b600061338f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134399092919063ffffffff16565b8051909150156114fe57808060200190518101906133ad919061395f565b6114fe5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109c5565b600054610100900460ff166134335760405162461bcd60e51b81526004016109c590613bff565b60018055565b60606134488484600085613452565b90505b9392505050565b6060824710156134b35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109c5565b6001600160a01b0385163b61350a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109c5565b600080866001600160a01b031685876040516135269190613c4a565b60006040518083038185875af1925050503d8060008114613563576040519150601f19603f3d011682016040523d82523d6000602084013e613568565b606091505b5091509150613578828286613583565b979650505050505050565b6060831561359257508161344b565b8251156135a25782518084602001fd5b8160405162461bcd60e51b81526004016109c59190613685565b8280546135c8906138be565b90600052602060002090601f0160209004810192826135ea5760008555613630565b82601f106136035782800160ff19823516178555613630565b82800160010185558215613630579182015b82811115613630578235825591602001919060010190613615565b5061363c929150613640565b5090565b5b8082111561363c5760008155600101613641565b60005b83811015613670578181015183820152602001613658565b8381111561367f576000848401525b50505050565b60208152600082518060208401526136a4816040850160208701613655565b601f01601f19169190910160400192915050565b6001600160a01b038116811461105657600080fd5b600080604083850312156136e057600080fd5b82356136eb816136b8565b946020939093013593505050565b60006020828403121561370b57600080fd5b5035919050565b60008060006060848603121561372757600080fd5b8335613732816136b8565b92506020840135613742816136b8565b929592945050506040919091013590565b60006020828403121561376557600080fd5b813561344b816136b8565b60008083601f84011261378257600080fd5b50813567ffffffffffffffff81111561379a57600080fd5b6020830191508360208285010111156137b257600080fd5b9250929050565b60008060008060008060008060c0898b0312156137d557600080fd5b883567ffffffffffffffff808211156137ed57600080fd5b6137f98c838d01613770565b909a50985060208b013591508082111561381257600080fd5b5061381f8b828c01613770565b9097509550506040890135613833816136b8565b93506060890135613843816136b8565b979a969950949793969295929450505060808201359160a0013590565b6000806040838503121561387357600080fd5b823591506020830135613885816136b8565b809150509250929050565b600080604083850312156138a357600080fd5b82356138ae816136b8565b91506020830135613885816136b8565b600181811c908216806138d257607f821691505b602082108114156138f357634e487b7160e01b600052602260045260246000fd5b50919050565b8051613296816136b8565b60006020828403121561391657600080fd5b815161344b816136b8565b634e487b7160e01b600052601160045260246000fd5b6000821982111561394a5761394a613921565b500190565b8051801515811461329657600080fd5b60006020828403121561397157600080fd5b612c378261394f565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000602082840312156139c357600080fd5b5051919050565b6000828210156139dc576139dc613921565b500390565b6001600160a01b03929092168252602082015260400190565b6000816000190483118215151615613a1457613a14613921565b500290565b600082613a3657634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215613a4d57600080fd5b815160ff8116811461344b57600080fd5b600080600080600060a08688031215613a7657600080fd5b613a7f8661394f565b602087015160408801516060890151608090990151929a91995097965090945092505050565b634e487b7160e01b600052604160045260246000fd5b60006020808385031215613ace57600080fd5b825167ffffffffffffffff80821115613ae657600080fd5b818501915085601f830112613afa57600080fd5b815181811115613b0c57613b0c613aa5565b8060051b604051601f19603f83011681018181108582111715613b3157613b31613aa5565b604052918252848201925083810185019188831115613b4f57600080fd5b938501935b82851015613b7457613b65856138f9565b84529385019392850192613b54565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b6000600019821415613baa57613baa613921565b5060010190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008251613c5c818460208701613655565b919091019291505056fea26469706673582212202a942e4446d0845826179dd94c6f9bde886db2b71bc4497729679f81e179a56a64736f6c63430008090033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.