| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| 0xb7fce3cc5ac9ad069fe8fd420eeab3a8079cec83e8cfd16191a4095e886e05a2 | - | (pending) | 8 days ago | IN | 0.0051723751 ETH | (Pending) | |||
| 0x1a45e0878c4750498b654043ff82d6c9d32b133c00b163cd458ade149d5b17d2 | - | (pending) | 66 days ago | IN | 0.0111947513 ETH | (Pending) | |||
| Execute | 25972844 | 61 days ago | IN | 0.0001797 ETH | 0.00001149 | ||||
| Execute | 25972670 | 61 days ago | IN | 0.00018315 ETH | 0.0000109 | ||||
| Execute | 25819280 | 66 days ago | IN | 0.00682598 ETH | 0.0000043 | ||||
| Execute | 25611358 | 72 days ago | IN | 0.00055325 ETH | 0.00001672 | ||||
| Execute | 25573765 | 73 days ago | IN | 0.00484099 ETH | 0.00002527 | ||||
| Execute | 25573595 | 73 days ago | IN | 0.00515277 ETH | 0.00002033 | ||||
| Execute | 25573425 | 73 days ago | IN | 0.01014251 ETH | 0.0000214 | ||||
| Execute | 25263761 | 81 days ago | IN | 0.00014604 ETH | 0.00001153 | ||||
| Execute | 25057847 | 86 days ago | IN | 0.00240844 ETH | 0.00002411 | ||||
| Execute | 24933340 | 90 days ago | IN | 0.02415208 ETH | 0.00002583 | ||||
| Execute | 24816501 | 93 days ago | IN | 0.00113161 ETH | 0.0000252 | ||||
| Execute | 24803999 | 94 days ago | IN | 0.00113394 ETH | 0.00001829 | ||||
| Execute | 24803971 | 94 days ago | IN | 0.00023495 ETH | 0.00002278 | ||||
| Execute | 24799332 | 94 days ago | IN | 0.00095554 ETH | 0.00001781 | ||||
| Execute | 24799281 | 94 days ago | IN | 0.00105243 ETH | 0.00002583 | ||||
| Execute | 24799180 | 94 days ago | IN | 0.00413217 ETH | 0.0000201 | ||||
| Execute | 24799141 | 94 days ago | IN | 0.00323229 ETH | 0.00002128 | ||||
| Execute | 24644719 | 99 days ago | IN | 0.00092286 ETH | 0.00001877 | ||||
| Execute | 24644674 | 99 days ago | IN | 0.00192121 ETH | 0.00001938 | ||||
| Execute | 24644617 | 99 days ago | IN | 0.00111428 ETH | 0.00002055 | ||||
| Execute | 24644546 | 99 days ago | IN | 0.00313123 ETH | 0.00002009 | ||||
| Execute | 24562545 | 101 days ago | IN | 0.00012305 ETH | 0.00001342 | ||||
| Execute | 24537655 | 101 days ago | IN | 0.00112288 ETH | 0.00001985 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 26753453 | 39 days ago | 0 ETH | ||||
| 26753453 | 39 days ago | 0.00895429 ETH | ||||
| 26753453 | 39 days ago | 0 ETH | ||||
| 26753453 | 39 days ago | 0.00895429 ETH | ||||
| 26753453 | 39 days ago | 0 ETH | ||||
| 26753453 | 39 days ago | 0 ETH | ||||
| 26753453 | 39 days ago | 0 ETH | ||||
| 26753453 | 39 days ago | 0 ETH | ||||
| 26753453 | 39 days ago | 0 ETH | ||||
| 26753453 | 39 days ago | 0 ETH | ||||
| 26753453 | 39 days ago | 0 ETH | ||||
| 26058734 | 58 days ago | 0 ETH | ||||
| 26058734 | 58 days ago | 0.18993647 ETH | ||||
| 26058734 | 58 days ago | 0 ETH | ||||
| 26058734 | 58 days ago | 0.18993647 ETH | ||||
| 26058734 | 58 days ago | 0 ETH | ||||
| 26058734 | 58 days ago | 0 ETH | ||||
| 26058734 | 58 days ago | 0 ETH | ||||
| 26058734 | 58 days ago | 0 ETH | ||||
| 26058734 | 58 days ago | 0 ETH | ||||
| 26058734 | 58 days ago | 0 ETH | ||||
| 26058734 | 58 days ago | 0 ETH | ||||
| 25982502 | 61 days ago | 0 ETH | ||||
| 25982502 | 61 days ago | 0.00000396 ETH | ||||
| 25982502 | 61 days ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ActionExecutor
Compiler Version
v0.8.22+commit.4fc1097e
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
import { ReentrancyGuard } from '@openzeppelin/contracts/security/ReentrancyGuard.sol';
import { IActionDataStructures } from './interfaces/IActionDataStructures.sol';
import { IGateway } from './crosschain/interfaces/IGateway.sol';
import { IGatewayClient } from './crosschain/interfaces/IGatewayClient.sol';
import { IRegistry } from './interfaces/IRegistry.sol';
import { ISettings } from './interfaces/ISettings.sol';
import { BalanceManagement } from './BalanceManagement.sol';
import { CallerGuard } from './CallerGuard.sol';
import { Pausable } from './Pausable.sol';
import { SystemVersionId } from './SystemVersionId.sol';
import { ZeroAddressError } from './Errors.sol';
import './helpers/AddressHelper.sol' as AddressHelper;
import './helpers/GasReserveHelper.sol' as GasReserveHelper;
import './helpers/RefundHelper.sol' as RefundHelper;
import './helpers/TransferHelper.sol' as TransferHelper;
import './Constants.sol' as Constants;
/**
* @title ActionExecutor
* @notice The main contract for cross-chain swaps
*/
contract ActionExecutor is
SystemVersionId,
Pausable,
ReentrancyGuard,
CallerGuard,
BalanceManagement,
IGatewayClient,
ISettings,
IActionDataStructures
{
/**
* @dev The contract for action settings
*/
IRegistry public registry;
uint256 private lastActionId = block.chainid * 1e11 + 55555 ** 2;
/**
* @notice Emitted when source chain action is performed
* @param actionId The ID of the action
* @param targetChainId The ID of the target chain
* @param sourceSender The address of the user on the source chain
* @param targetRecipient The address of the recipient on the target chain
* @param gatewayType The type of cross-chain gateway
* @param assetType The type of the asset (gateway-specific)
* @param routerType The type of the swap router
* @param inputTokenAmountData The input token amount data
* @param assetTokenAmountData The asset token amount data
* @param targetToken The address of the output token on the target chain
* @param timestamp The timestamp of the action (in seconds)
*/
event ActionSource(
uint256 indexed actionId,
uint256 indexed targetChainId,
address indexed sourceSender,
address targetRecipient,
uint256 gatewayType,
uint256 assetType,
uint256 routerType,
TokenAmountData inputTokenAmountData,
TokenAmountData assetTokenAmountData,
address targetToken,
uint256 timestamp
);
/**
* @notice Emitted when target chain action is performed
* @param actionId The ID of the action
* @param sourceChainId The ID of the source chain
* @param recipient The address of the recipient
* @param gatewayType The type of the gateway
* @param assetType The type of the asset (gateway-specific)
* @param routerType The type of the swap router
* @param assetTokenAmountData The asset token amount data
* @param outputTokenAmountData The output token amount data
* @param outputExtraAmount The output extra amount
* @param isSuccess The status of the action execution
* @param timestamp The timestamp of the action (in seconds)
*/
event ActionTarget(
uint256 indexed actionId,
uint256 indexed sourceChainId,
address indexed recipient,
uint256 gatewayType,
uint256 assetType,
uint256 routerType,
TokenAmountData assetTokenAmountData,
TokenAmountData outputTokenAmountData,
uint256 outputExtraAmount,
bool isSuccess,
uint256 timestamp
);
/**
* @notice Emitted when the Registry contract address is updated
* @param registryAddress The address of the Registry contract
*/
event SetRegistry(address indexed registryAddress);
/**
* @notice Emitted when the caller is not a registered cross-chain gateway
*/
error OnlyGatewayError();
/**
* @notice Emitted when the call is not from the current contract
*/
error OnlySelfError();
/**
* @notice Emitted when a cross-chain swap is attempted with the target chain ID matching the current chain
*/
error SameChainIdError();
/**
* @notice Emitted when the native token value of the transaction does not correspond to the swap amount
*/
error NativeTokenValueError();
/**
* @notice Emitted when the requested cross-chain gateway type is not set
*/
error GatewayNotSetError();
/**
* @notice Emitted when the requested swap router type is not set
*/
error RouterNotSetError();
/**
* @notice Emitted when the swap process results in an error
*/
error SwapError();
/**
* @notice Emitted when the target amount is insufficient
* @param expectedAmount Expected amount
* @param actualAmount Actual amount
*/
error TargetAmountError(uint256 expectedAmount, uint256 actualAmount);
/**
* @dev Modifier to check if the caller is the current contract
*/
modifier onlySelf() {
if (msg.sender != address(this)) {
revert OnlySelfError();
}
_;
}
/**
* @notice Deploys the ActionExecutor contract
* @param _registry The address of the action settings registry contract
* @param _actionIdOffset The initial offset of the action ID value
* @param _owner The address of the initial owner of the contract
* @param _managers The addresses of initial managers of the contract
* @param _addOwnerToManagers The flag to optionally add the owner to the list of managers
*/
constructor(
IRegistry _registry,
uint256 _actionIdOffset,
address _owner,
address[] memory _managers,
bool _addOwnerToManagers
) {
if (address(_registry) != address(0)) {
_setRegistry(_registry);
}
lastActionId += _actionIdOffset;
callerGuardMode = CallerGuardMode.ContractAllowed;
_initRoles(_owner, _managers, _addOwnerToManagers);
}
/**
* @notice The standard "receive" function
* @dev Is payable to allow receiving native token funds from a target swap router
*/
receive() external payable {}
/**
* @notice Sets the address of the action settings registry contract
* @param _registry The address of the action settings registry contract
*/
function setRegistry(IRegistry _registry) external onlyManager {
_setRegistry(_registry);
}
/**
* @notice Executes a cross-chain action
* @param _action The parameters of the action
*/
function execute(
Action calldata _action
) external payable whenNotPaused nonReentrant checkCaller returns (uint256 actionId) {
if (_action.targetChainId == block.chainid) {
revert SameChainIdError();
}
// For cross-chain swaps of the native token,
// the value of the transaction should be greater or equal to the swap amount
if (
_action.sourceTokenAddress == Constants.NATIVE_TOKEN_ADDRESS &&
msg.value < _action.sourceSwapInfo.fromAmount
) {
revert NativeTokenValueError();
}
uint256 initialBalance = address(this).balance - msg.value;
lastActionId++;
actionId = lastActionId;
SourceSettings memory settings = registry.sourceSettings(
_action.gatewayType,
_action.sourceSwapInfo.routerType
);
if (settings.gateway == address(0)) {
revert GatewayNotSetError();
}
address assetTokenAddress = IGateway(settings.gateway).assetByType(_action.assetType);
if (assetTokenAddress == address(0)) {
revert ZeroAddressError();
}
(uint256 assetAmount, uint256 nativeTokenSpent) = _processSource(
_action.sourceTokenAddress,
assetTokenAddress,
_action.sourceSwapInfo,
settings.router,
settings.routerTransfer
);
AssetAmountData memory assetAmountData = AssetAmountData({
assetType: _action.assetType,
amount: assetAmount
});
uint256 targetAmountLD = IGateway(settings.gateway).targetAmountLD(
_action.targetChainId,
assetAmountData
);
if (targetAmountLD < _action.minTargetAmountLD) {
revert TargetAmountError(_action.minTargetAmountLD, targetAmountLD);
}
bytes memory targetMessageData = abi.encode(
TargetMessage({
actionId: actionId,
sourceSender: msg.sender,
gatewayType: _action.gatewayType,
assetType: _action.assetType,
targetTokenAddress: _action.targetTokenAddress,
targetSwapInfo: _action.targetSwapInfo,
targetRecipient: _action.targetRecipient == address(0)
? msg.sender
: _action.targetRecipient,
targetGasReserveOverride: _action.targetGasReserveOverride
})
);
_sendMessage(
settings,
_action,
targetMessageData,
assetAmountData,
assetTokenAddress,
msg.value - nativeTokenSpent
);
// - - - Extra balance transfer - - -
RefundHelper.refundExtraBalance(address(this), initialBalance, payable(msg.sender));
// - - -
_emitActionSourceEvent(actionId, _action, assetTokenAddress, assetAmount);
}
/**
* @notice Cross-chain message handler on the target chain
* @dev The function is called by cross-chain gateways
* @param _messageSourceChainId The ID of the message source chain
* @param _payloadData The content of the cross-chain message
* @param _assetTokenAddress The asset token address
* @param _assetAmount The asset amount
*/
function handleExecutionPayload(
uint256 _messageSourceChainId,
bytes calldata _payloadData,
address _assetTokenAddress,
uint256 _assetAmount
) external payable whenNotPaused {
TargetMessage memory targetMessage = abi.decode(_payloadData, (TargetMessage));
if (msg.sender != registry.gatewayMap(targetMessage.gatewayType)) {
revert OnlyGatewayError();
}
if (_assetAmount < targetMessage.targetSwapInfo.fromAmount) {
revert TargetAmountError(targetMessage.targetSwapInfo.fromAmount, _assetAmount);
}
TargetSettings memory settings = registry.targetSettings(
targetMessage.targetSwapInfo.routerType
);
TransferHelper.safeTransferFrom(
_assetTokenAddress,
msg.sender,
address(this),
_assetAmount
);
bool targetSuccess;
uint256 outputAmount;
uint256 outputExtraAmount;
uint256 assetTransferAmount;
if (targetMessage.targetTokenAddress == _assetTokenAddress) {
// (no swap)
targetSuccess = true;
outputAmount = _assetAmount;
// outputExtraAmount is 0 by default
assetTransferAmount = _assetAmount;
} else {
(bool hasGasReserve, uint256 gasAllowed) = GasReserveHelper.checkGasReserve(
targetMessage.targetGasReserveOverride != 0
? targetMessage.targetGasReserveOverride
: settings.gasReserve
);
if (hasGasReserve) {
try
this.selfCallTarget{ gas: gasAllowed }(
settings,
targetMessage,
_assetTokenAddress
)
returns (uint256 selfCallOutputAmount) {
targetSuccess = true;
outputAmount = selfCallOutputAmount;
outputExtraAmount = _assetAmount - targetMessage.targetSwapInfo.fromAmount;
} catch {}
}
if (!targetSuccess) {
// outputAmount is 0 by default
outputExtraAmount = _assetAmount;
}
assetTransferAmount = outputExtraAmount;
}
if (assetTransferAmount > 0) {
TransferHelper.safeTransfer(
_assetTokenAddress,
targetMessage.targetRecipient,
assetTransferAmount
);
}
_emitActionTargetEvent(
_messageSourceChainId,
targetMessage,
_assetTokenAddress,
_assetAmount,
targetMessage.targetTokenAddress,
outputAmount,
outputExtraAmount,
targetSuccess
);
}
/**
* @notice Controllable processing of the target chain logic
* @dev Is called by the current contract to enable error handling
* @param _settings Target action settings
* @param _targetMessage The content of the cross-chain message
* @param _fromTokenAddress The "from" token address
* @return outputAmount The output amount
*/
function selfCallTarget(
TargetSettings calldata _settings,
TargetMessage calldata _targetMessage,
address _fromTokenAddress
) external onlySelf returns (uint256 outputAmount) {
return
_processTarget(
_settings,
_fromTokenAddress,
_targetMessage.targetTokenAddress,
_targetMessage.targetSwapInfo,
_targetMessage.targetRecipient
);
}
function _processSource(
address _fromTokenAddress,
address _toTokenAddress,
SwapInfo memory _sourceSwapInfo,
address _routerAddress,
address _routerTransferAddress
) private returns (uint256 resultAmount, uint256 nativeTokenSpent) {
if (_fromTokenAddress == Constants.NATIVE_TOKEN_ADDRESS) {
if (_toTokenAddress == Constants.NATIVE_TOKEN_ADDRESS) {
resultAmount = _sourceSwapInfo.fromAmount;
nativeTokenSpent = resultAmount;
} else {
uint256 toTokenBalanceBefore = tokenBalance(_toTokenAddress);
if (_routerAddress == address(0)) {
revert RouterNotSetError();
}
// - - - Source swap (native token) - - -
(bool routerCallSuccess, ) = payable(_routerAddress).call{
value: _sourceSwapInfo.fromAmount
}(_sourceSwapInfo.routerData);
if (!routerCallSuccess) {
revert SwapError();
}
// - - -
resultAmount = tokenBalance(_toTokenAddress) - toTokenBalanceBefore;
nativeTokenSpent = _sourceSwapInfo.fromAmount;
}
} else {
if (_fromTokenAddress != _toTokenAddress && _routerAddress == address(0)) {
revert RouterNotSetError();
}
uint256 toTokenBalanceBefore = tokenBalance(_toTokenAddress);
TransferHelper.safeTransferFrom(
_fromTokenAddress,
msg.sender,
address(this),
_sourceSwapInfo.fromAmount
);
if (_fromTokenAddress != _toTokenAddress) {
// - - - Source swap (non-native token) - - -
TransferHelper.safeApprove(
_fromTokenAddress,
_routerTransferAddress,
_sourceSwapInfo.fromAmount
);
(bool routerCallSuccess, ) = _routerAddress.call(_sourceSwapInfo.routerData);
if (!routerCallSuccess) {
revert SwapError();
}
TransferHelper.safeApprove(_fromTokenAddress, _routerTransferAddress, 0);
// - - -
}
resultAmount = tokenBalance(_toTokenAddress) - toTokenBalanceBefore;
nativeTokenSpent = 0;
}
}
function _processTarget(
TargetSettings memory _settings,
address _fromTokenAddress,
address _toTokenAddress,
SwapInfo memory _targetSwapInfo,
address _targetRecipient
) private returns (uint256 outputAmount) {
if (_settings.router == address(0)) {
revert RouterNotSetError();
}
uint256 toTokenBalanceBefore = tokenBalance(_toTokenAddress);
// - - - Target swap - - -
TransferHelper.safeApprove(
_fromTokenAddress,
_settings.routerTransfer,
_targetSwapInfo.fromAmount
);
(bool success, ) = _settings.router.call(_targetSwapInfo.routerData);
if (!success) {
revert SwapError();
}
TransferHelper.safeApprove(_fromTokenAddress, _settings.routerTransfer, 0);
// - - -
outputAmount = tokenBalance(_toTokenAddress) - toTokenBalanceBefore;
if (_toTokenAddress == Constants.NATIVE_TOKEN_ADDRESS) {
TransferHelper.safeTransferNative(_targetRecipient, outputAmount);
} else {
TransferHelper.safeTransfer(_toTokenAddress, _targetRecipient, outputAmount);
}
}
function _setRegistry(IRegistry _registry) private {
AddressHelper.requireContract(address(_registry));
registry = _registry;
emit SetRegistry(address(_registry));
}
function _sendMessage(
SourceSettings memory _settings,
Action calldata _action,
bytes memory _messageData,
AssetAmountData memory _assetAmountData,
address _assetTokenAddress,
uint256 _availableValue
) private {
TransferHelper.safeApprove(_assetTokenAddress, _settings.gateway, _assetAmountData.amount);
IGateway(_settings.gateway).sendMessage{ value: _availableValue }(
_action.targetChainId,
_messageData,
_action.gatewaySettings,
_assetAmountData
);
TransferHelper.safeApprove(_assetTokenAddress, _settings.gateway, 0);
}
function _emitActionSourceEvent(
uint256 _actionId,
Action calldata _action,
address _assetTokenAddress,
uint256 _assetAmount
) private {
emit ActionSource(
_actionId,
_action.targetChainId,
msg.sender,
_action.targetRecipient,
_action.gatewayType,
_action.assetType,
_action.sourceSwapInfo.routerType,
TokenAmountData({
tokenAddress: _action.sourceTokenAddress,
amount: _action.sourceSwapInfo.fromAmount
}),
TokenAmountData({ tokenAddress: _assetTokenAddress, amount: _assetAmount }),
_action.targetTokenAddress,
block.timestamp
);
}
function _emitActionTargetEvent(
uint256 _messageSourceChainId,
TargetMessage memory _targetMessage,
address _assetTokenAddress,
uint256 _assetAmount,
address _outputTokenAddress,
uint256 _outputAmount,
uint256 _outputExtraAmount,
bool _isSuccess
) private {
emit ActionTarget(
_targetMessage.actionId,
_messageSourceChainId,
_targetMessage.targetRecipient,
_targetMessage.gatewayType,
_targetMessage.assetType,
_targetMessage.targetSwapInfo.routerType,
TokenAmountData({ tokenAddress: _assetTokenAddress, amount: _assetAmount }),
TokenAmountData({ tokenAddress: _outputTokenAddress, amount: _outputAmount }),
_outputExtraAmount,
_isSuccess,
block.timestamp
);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_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() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// 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
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
import { ITokenBalance } from './interfaces/ITokenBalance.sol';
import { ManagerRole } from './roles/ManagerRole.sol';
import './helpers/TransferHelper.sol' as TransferHelper;
import './Constants.sol' as Constants;
/**
* @title BalanceManagement
* @notice Base contract for the withdrawal of tokens, except for reserved ones
*/
abstract contract BalanceManagement is ManagerRole {
/**
* @notice Emitted when the specified token is reserved
*/
error ReservedTokenError();
/**
* @notice Performs the withdrawal of tokens, except for reserved ones
* @dev Use the "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" address for the native token
* @param _tokenAddress The address of the token
* @param _tokenAmount The amount of the token
*/
function cleanup(address _tokenAddress, uint256 _tokenAmount) external onlyManager {
if (isReservedToken(_tokenAddress)) {
revert ReservedTokenError();
}
if (_tokenAddress == Constants.NATIVE_TOKEN_ADDRESS) {
TransferHelper.safeTransferNative(msg.sender, _tokenAmount);
} else {
TransferHelper.safeTransfer(_tokenAddress, msg.sender, _tokenAmount);
}
}
/**
* @notice Getter of the token balance of the current contract
* @dev Use the "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" address for the native token
* @param _tokenAddress The address of the token
* @return The token balance of the current contract
*/
function tokenBalance(address _tokenAddress) public view returns (uint256) {
if (_tokenAddress == Constants.NATIVE_TOKEN_ADDRESS) {
return address(this).balance;
} else {
return ITokenBalance(_tokenAddress).balanceOf(address(this));
}
}
/**
* @notice Getter of the reserved token flag
* @dev Override to add reserved token addresses
* @param _tokenAddress The address of the token
* @return The reserved token flag
*/
function isReservedToken(address _tokenAddress) public view virtual returns (bool) {
// The function returns false by default.
// The explicit return statement is omitted to avoid the unused parameter warning.
// See https://github.com/ethereum/solidity/issues/5295
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
import { ManagerRole } from './roles/ManagerRole.sol';
import './helpers/AddressHelper.sol' as AddressHelper;
import './Constants.sol' as Constants;
import './DataStructures.sol' as DataStructures;
/**
* @title CallerGuard
* @notice Base contract to control access from other contracts
*/
abstract contract CallerGuard is ManagerRole {
/**
* @dev Caller guard mode enumeration
*/
enum CallerGuardMode {
ContractForbidden,
ContractList,
ContractAllowed
}
/**
* @dev Caller guard mode value
*/
CallerGuardMode public callerGuardMode = CallerGuardMode.ContractForbidden;
/**
* @dev Registered contract list for "ContractList" mode
*/
address[] public listedCallerGuardContractList;
/**
* @dev Registered contract list indices for "ContractList" mode
*/
mapping(address /*account*/ => DataStructures.OptionalValue /*index*/)
public listedCallerGuardContractIndexMap;
/**
* @notice Emitted when the caller guard mode is set
* @param callerGuardMode The caller guard mode
*/
event SetCallerGuardMode(CallerGuardMode indexed callerGuardMode);
/**
* @notice Emitted when a registered contract for "ContractList" mode is added or removed
* @param contractAddress The contract address
* @param isListed The registered contract list inclusion flag
*/
event SetListedCallerGuardContract(address indexed contractAddress, bool indexed isListed);
/**
* @notice Emitted when the caller is not allowed to perform the intended action
*/
error CallerGuardError(address caller);
/**
* @dev Modifier to check if the caller is allowed to perform the intended action
*/
modifier checkCaller() {
if (msg.sender != tx.origin) {
bool condition = (callerGuardMode == CallerGuardMode.ContractAllowed ||
(callerGuardMode == CallerGuardMode.ContractList &&
isListedCallerGuardContract(msg.sender)));
if (!condition) {
revert CallerGuardError(msg.sender);
}
}
_;
}
/**
* @notice Sets the caller guard mode
* @param _callerGuardMode The caller guard mode
*/
function setCallerGuardMode(CallerGuardMode _callerGuardMode) external onlyManager {
callerGuardMode = _callerGuardMode;
emit SetCallerGuardMode(_callerGuardMode);
}
/**
* @notice Updates the list of registered contracts for the "ContractList" mode
* @param _items The addresses and flags for the contracts
*/
function setListedCallerGuardContracts(
DataStructures.AccountToFlag[] calldata _items
) external onlyManager {
for (uint256 index; index < _items.length; index++) {
DataStructures.AccountToFlag calldata item = _items[index];
if (item.flag) {
AddressHelper.requireContract(item.account);
}
DataStructures.uniqueAddressListUpdate(
listedCallerGuardContractList,
listedCallerGuardContractIndexMap,
item.account,
item.flag,
Constants.LIST_SIZE_LIMIT_DEFAULT
);
emit SetListedCallerGuardContract(item.account, item.flag);
}
}
/**
* @notice Getter of the registered contract count
* @return The registered contract count
*/
function listedCallerGuardContractCount() external view returns (uint256) {
return listedCallerGuardContractList.length;
}
/**
* @notice Getter of the complete list of registered contracts
* @return The complete list of registered contracts
*/
function fullListedCallerGuardContractList() external view returns (address[] memory) {
return listedCallerGuardContractList;
}
/**
* @notice Getter of a listed contract flag
* @param _account The contract address
* @return The listed contract flag
*/
function isListedCallerGuardContract(address _account) public view returns (bool) {
return listedCallerGuardContractIndexMap[_account].isSet;
}
}// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.22; /** * @dev The default token decimals value */ uint256 constant DECIMALS_DEFAULT = 18; /** * @dev The maximum uint256 value for swap amount limit settings */ uint256 constant INFINITY = type(uint256).max; /** * @dev The default limit of account list size */ uint256 constant LIST_SIZE_LIMIT_DEFAULT = 100; /** * @dev The limit of swap router list size */ uint256 constant LIST_SIZE_LIMIT_ROUTERS = 200; /** * @dev The factor for percentage settings. Example: 100 is 0.1% */ uint256 constant MILLIPERCENT_FACTOR = 100_000; /** * @dev The de facto standard address to denote the native token */ address constant NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
import { IAssetDataStructures } from '../../interfaces/IAssetDataStructures.sol';
/**
* @title IGateway
* @notice Cross-chain gateway interface
*/
interface IGateway is IAssetDataStructures {
/**
* @notice Send a cross-chain message
* @param _targetChainId The message target chain ID
* @param _appMessage The app message content
* @param _settings The gateway-specific settings
* @param _assetAmountData The asset amount data
*/
function sendMessage(
uint256 _targetChainId,
bytes calldata _appMessage,
bytes calldata _settings,
AssetAmountData calldata _assetAmountData
) external payable;
/**
* @notice Cross-chain message fee estimation (native token fee only)
* @param _targetChainId The ID of the target chain
* @param _appMessage The app message content
* @param _settings The gateway-specific settings
* @param _assetAmountData The asset amount data
* @return nativeFee Message fee (native token)
*/
function messageFee(
uint256 _targetChainId,
bytes calldata _appMessage,
bytes calldata _settings,
AssetAmountData calldata _assetAmountData
) external view returns (uint256 nativeFee);
/**
* @notice Target chain amount estimation (local decimals)
* @param _targetChainId The ID of the target chain
* @param _assetAmountData The asset amount data
* @return amount Target chain amount
*/
function targetAmountLD(
uint256 _targetChainId,
AssetAmountData calldata _assetAmountData
) external view returns (uint256 amount);
/**
* @notice Asset transfer limits
* @param _targetChainId The ID of the target chain
* @param _assetType The asset type
* @return limit Asset transfer limit in SD (shared decimals)
* @return sharedDecimals Shared decimals
*/
function assetLimit(
uint256 _targetChainId,
uint256 _assetType
) external view returns (uint256 limit, uint8 sharedDecimals);
/**
* @notice Asset address by type
* @param _assetType The asset type
* @return The asset address
*/
function assetByType(uint256 _assetType) external view returns (address);
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
import { IAssetDataStructures } from '../../interfaces/IAssetDataStructures.sol';
/**
* @title IGatewayClient
* @notice Cross-chain gateway client interface
*/
interface IGatewayClient is IAssetDataStructures {
/**
* @notice Cross-chain message handler on the target chain
* @dev The function is called by cross-chain gateways
* @param _messageSourceChainId The ID of the message source chain
* @param _payloadData The content of the cross-chain message
* @param _assetTokenAddress The asset token address
* @param _assetAmount The asset amount
*/
function handleExecutionPayload(
uint256 _messageSourceChainId,
bytes calldata _payloadData,
address _assetTokenAddress,
uint256 _assetAmount
) external payable;
/**
* @notice The standard "receive" function
*/
receive() external payable;
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
/**
* @notice Optional value structure
* @dev Is used in mappings to allow zero values
* @param isSet Value presence flag
* @param value Numeric value
*/
struct OptionalValue {
bool isSet;
uint256 value;
}
/**
* @notice Key-to-value structure
* @dev Is used as an array parameter item to perform multiple key-value settings
* @param key Numeric key
* @param value Numeric value
*/
struct KeyToValue {
uint256 key;
uint256 value;
}
/**
* @notice Key-to-value structure for address values
* @dev Is used as an array parameter item to perform multiple key-value settings with address values
* @param key Numeric key
* @param value Address value
*/
struct KeyToAddressValue {
uint256 key;
address value;
}
/**
* @notice Address-to-flag structure
* @dev Is used as an array parameter item to perform multiple settings
* @param account Account address
* @param flag Flag value
*/
struct AccountToFlag {
address account;
bool flag;
}
/**
* @notice Emitted when a list exceeds the size limit
*/
error ListSizeLimitError();
/**
* @notice Sets or updates a value in a combined map (a mapping with a key list and key index mapping)
* @param _map The mapping reference
* @param _keyList The key list reference
* @param _keyIndexMap The key list index mapping reference
* @param _key The numeric key
* @param _value The address value
* @param _sizeLimit The map and list size limit
* @return isNewKey True if the key was just added, otherwise false
*/
function combinedMapSet(
mapping(uint256 => address) storage _map,
uint256[] storage _keyList,
mapping(uint256 => OptionalValue) storage _keyIndexMap,
uint256 _key,
address _value,
uint256 _sizeLimit
) returns (bool isNewKey) {
isNewKey = !_keyIndexMap[_key].isSet;
if (isNewKey) {
uniqueListAdd(_keyList, _keyIndexMap, _key, _sizeLimit);
}
_map[_key] = _value;
}
/**
* @notice Removes a value from a combined map (a mapping with a key list and key index mapping)
* @param _map The mapping reference
* @param _keyList The key list reference
* @param _keyIndexMap The key list index mapping reference
* @param _key The numeric key
* @return isChanged True if the combined map was changed, otherwise false
*/
function combinedMapRemove(
mapping(uint256 => address) storage _map,
uint256[] storage _keyList,
mapping(uint256 => OptionalValue) storage _keyIndexMap,
uint256 _key
) returns (bool isChanged) {
isChanged = _keyIndexMap[_key].isSet;
if (isChanged) {
delete _map[_key];
uniqueListRemove(_keyList, _keyIndexMap, _key);
}
}
/**
* @notice Sets or updates a value in a combined double map (two mappings with a key list and key index mapping)
* @param _map1 The first mapping reference
* @param _map2 The second mapping reference
* @param _keyList The key list reference
* @param _keyIndexMap The key list index mapping reference
* @param _key The numeric key
* @param _value1 The first address value
* @param _value2 The second address value
* @param _sizeLimit The map and list size limit
* @return isNewKey True if the key was just added, otherwise false
*/
function combinedDoubleMapSet(
mapping(uint256 => address) storage _map1,
mapping(uint256 => address) storage _map2,
uint256[] storage _keyList,
mapping(uint256 => OptionalValue) storage _keyIndexMap,
uint256 _key,
address _value1,
address _value2,
uint256 _sizeLimit
) returns (bool isNewKey) {
isNewKey = !_keyIndexMap[_key].isSet;
if (isNewKey) {
uniqueListAdd(_keyList, _keyIndexMap, _key, _sizeLimit);
}
_map1[_key] = _value1;
_map2[_key] = _value2;
}
/**
* @notice Removes a value from a combined double map (two mappings with a key list and key index mapping)
* @param _map1 The first mapping reference
* @param _map2 The second mapping reference
* @param _keyList The key list reference
* @param _keyIndexMap The key list index mapping reference
* @param _key The numeric key
* @return isChanged True if the combined map was changed, otherwise false
*/
function combinedDoubleMapRemove(
mapping(uint256 => address) storage _map1,
mapping(uint256 => address) storage _map2,
uint256[] storage _keyList,
mapping(uint256 => OptionalValue) storage _keyIndexMap,
uint256 _key
) returns (bool isChanged) {
isChanged = _keyIndexMap[_key].isSet;
if (isChanged) {
delete _map1[_key];
delete _map2[_key];
uniqueListRemove(_keyList, _keyIndexMap, _key);
}
}
/**
* @notice Adds a value to a unique value list (a list with value index mapping)
* @param _list The list reference
* @param _indexMap The value index mapping reference
* @param _value The numeric value
* @param _sizeLimit The list size limit
* @return isChanged True if the list was changed, otherwise false
*/
function uniqueListAdd(
uint256[] storage _list,
mapping(uint256 => OptionalValue) storage _indexMap,
uint256 _value,
uint256 _sizeLimit
) returns (bool isChanged) {
isChanged = !_indexMap[_value].isSet;
if (isChanged) {
if (_list.length >= _sizeLimit) {
revert ListSizeLimitError();
}
_indexMap[_value] = OptionalValue(true, _list.length);
_list.push(_value);
}
}
/**
* @notice Removes a value from a unique value list (a list with value index mapping)
* @param _list The list reference
* @param _indexMap The value index mapping reference
* @param _value The numeric value
* @return isChanged True if the list was changed, otherwise false
*/
function uniqueListRemove(
uint256[] storage _list,
mapping(uint256 => OptionalValue) storage _indexMap,
uint256 _value
) returns (bool isChanged) {
OptionalValue storage indexItem = _indexMap[_value];
isChanged = indexItem.isSet;
if (isChanged) {
uint256 itemIndex = indexItem.value;
uint256 lastIndex = _list.length - 1;
if (itemIndex != lastIndex) {
uint256 lastValue = _list[lastIndex];
_list[itemIndex] = lastValue;
_indexMap[lastValue].value = itemIndex;
}
_list.pop();
delete _indexMap[_value];
}
}
/**
* @notice Adds a value to a unique address value list (a list with value index mapping)
* @param _list The list reference
* @param _indexMap The value index mapping reference
* @param _value The address value
* @param _sizeLimit The list size limit
* @return isChanged True if the list was changed, otherwise false
*/
function uniqueAddressListAdd(
address[] storage _list,
mapping(address => OptionalValue) storage _indexMap,
address _value,
uint256 _sizeLimit
) returns (bool isChanged) {
isChanged = !_indexMap[_value].isSet;
if (isChanged) {
if (_list.length >= _sizeLimit) {
revert ListSizeLimitError();
}
_indexMap[_value] = OptionalValue(true, _list.length);
_list.push(_value);
}
}
/**
* @notice Removes a value from a unique address value list (a list with value index mapping)
* @param _list The list reference
* @param _indexMap The value index mapping reference
* @param _value The address value
* @return isChanged True if the list was changed, otherwise false
*/
function uniqueAddressListRemove(
address[] storage _list,
mapping(address => OptionalValue) storage _indexMap,
address _value
) returns (bool isChanged) {
OptionalValue storage indexItem = _indexMap[_value];
isChanged = indexItem.isSet;
if (isChanged) {
uint256 itemIndex = indexItem.value;
uint256 lastIndex = _list.length - 1;
if (itemIndex != lastIndex) {
address lastValue = _list[lastIndex];
_list[itemIndex] = lastValue;
_indexMap[lastValue].value = itemIndex;
}
_list.pop();
delete _indexMap[_value];
}
}
/**
* @notice Adds or removes a value to/from a unique address value list (a list with value index mapping)
* @dev The list size limit is checked on items adding only
* @param _list The list reference
* @param _indexMap The value index mapping reference
* @param _value The address value
* @param _flag The value inclusion flag
* @param _sizeLimit The list size limit
* @return isChanged True if the list was changed, otherwise false
*/
function uniqueAddressListUpdate(
address[] storage _list,
mapping(address => OptionalValue) storage _indexMap,
address _value,
bool _flag,
uint256 _sizeLimit
) returns (bool isChanged) {
return
_flag
? uniqueAddressListAdd(_list, _indexMap, _value, _sizeLimit)
: uniqueAddressListRemove(_list, _indexMap, _value);
}// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.22; /** * @notice Emitted when an attempt to burn a token fails */ error TokenBurnError(); /** * @notice Emitted when an attempt to mint a token fails */ error TokenMintError(); /** * @notice Emitted when a zero address is specified where it is not allowed */ error ZeroAddressError();
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
/**
* @notice Emitted when the account is not a contract
* @param account The account address
*/
error NonContractAddressError(address account);
/**
* @notice Function to check if the account is a contract
* @return The account contract status flag
*/
function isContract(address _account) view returns (bool) {
return _account.code.length > 0;
}
/**
* @notice Function to require an account to be a contract
*/
function requireContract(address _account) view {
if (!isContract(_account)) {
revert NonContractAddressError(_account);
}
}
/**
* @notice Function to require an account to be a contract or a zero address
*/
function requireContractOrZeroAddress(address _account) view {
if (_account != address(0)) {
requireContract(_account);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
/**
* @notice Function to check if the available gas matches the specified gas reserve value
* @param _gasReserve Gas reserve value
* @return hasGasReserve Flag of gas reserve availability
* @return gasAllowed The remaining gas quantity taking the reserve into account
*/
function checkGasReserve(
uint256 _gasReserve
) view returns (bool hasGasReserve, uint256 gasAllowed) {
uint256 gasLeft = gasleft();
hasGasReserve = gasLeft >= _gasReserve;
gasAllowed = hasGasReserve ? gasLeft - _gasReserve : 0;
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
import './TransferHelper.sol' as TransferHelper;
/**
* @notice Refunds the extra balance of the native token
* @dev Reverts on subtraction if the actual balance is less than expected
* @param _self The address of the executing contract
* @param _expectedBalance The expected native token balance value
* @param _to The refund receiver's address
*/
function refundExtraBalance(address _self, uint256 _expectedBalance, address payable _to) {
uint256 extraBalance = _self.balance - _expectedBalance;
if (extraBalance > 0) {
TransferHelper.safeTransferNative(_to, extraBalance);
}
}
/**
* @notice Refunds the extra balance of the native token
* @dev Reverts on subtraction if the actual balance is less than expected
* @param _self The address of the executing contract
* @param _expectedBalance The expected native token balance value
* @param _to The refund receiver's address
* @return extraBalance The extra balance of the native token
*/
function refundExtraBalanceWithResult(
address _self,
uint256 _expectedBalance,
address payable _to
) returns (uint256 extraBalance) {
extraBalance = _self.balance - _expectedBalance;
if (extraBalance > 0) {
TransferHelper.safeTransferNative(_to, extraBalance);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
/**
* @notice Emitted when an approval action fails
*/
error SafeApproveError();
/**
* @notice Emitted when a transfer action fails
*/
error SafeTransferError();
/**
* @notice Emitted when a transferFrom action fails
*/
error SafeTransferFromError();
/**
* @notice Emitted when a transfer of the native token fails
*/
error SafeTransferNativeError();
/**
* @notice Safely approve the token to the account
* @param _token The token address
* @param _to The token approval recipient address
* @param _value The token approval amount
*/
function safeApprove(address _token, address _to, uint256 _value) {
// 0x095ea7b3 is the selector for "approve(address,uint256)"
(bool success, bytes memory data) = _token.call(
abi.encodeWithSelector(0x095ea7b3, _to, _value)
);
bool condition = success && (data.length == 0 || abi.decode(data, (bool)));
if (!condition) {
revert SafeApproveError();
}
}
/**
* @notice Safely transfer the token to the account
* @param _token The token address
* @param _to The token transfer recipient address
* @param _value The token transfer amount
*/
function safeTransfer(address _token, address _to, uint256 _value) {
// 0xa9059cbb is the selector for "transfer(address,uint256)"
(bool success, bytes memory data) = _token.call(
abi.encodeWithSelector(0xa9059cbb, _to, _value)
);
bool condition = success && (data.length == 0 || abi.decode(data, (bool)));
if (!condition) {
revert SafeTransferError();
}
}
/**
* @notice Safely transfer the token between the accounts
* @param _token The token address
* @param _from The token transfer source address
* @param _to The token transfer recipient address
* @param _value The token transfer amount
*/
function safeTransferFrom(address _token, address _from, address _to, uint256 _value) {
// 0x23b872dd is the selector for "transferFrom(address,address,uint256)"
(bool success, bytes memory data) = _token.call(
abi.encodeWithSelector(0x23b872dd, _from, _to, _value)
);
bool condition = success && (data.length == 0 || abi.decode(data, (bool)));
if (!condition) {
revert SafeTransferFromError();
}
}
/**
* @notice Safely transfer the native token to the account
* @param _to The native token transfer recipient address
* @param _value The native token transfer amount
*/
function safeTransferNative(address _to, uint256 _value) {
(bool success, ) = _to.call{ value: _value }(new bytes(0));
if (!success) {
revert SafeTransferNativeError();
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
import { IAssetDataStructures } from './IAssetDataStructures.sol';
/**
* @title IActionDataStructures
* @notice Action data structure declarations
*/
interface IActionDataStructures is IAssetDataStructures {
/**
* @notice Cross-chain action data structure
* @param gatewayType The numeric type of the cross-chain gateway
* @param assetType The numeric type of the asset
* @param sourceTokenAddress The address of the input token on the source chain
* @param sourceSwapInfo The data for the source chain swap
* @param minTargetAmountLD The minimum target amount (source chain local decimals)
* @param targetChainId The action target chain ID
* @param targetTokenAddress The address of the output token on the destination chain
* @param targetSwapInfo The data for the target chain swap
* @param targetRecipient The address of the recipient on the target chain
* @param targetGasReserveOverride The target gas reserve override value
* @param gatewaySettings The gateway-specific settings data
*/
struct Action {
uint256 gatewayType;
uint256 assetType;
address sourceTokenAddress;
SwapInfo sourceSwapInfo;
uint256 minTargetAmountLD;
uint256 targetChainId;
address targetTokenAddress;
SwapInfo targetSwapInfo;
address targetRecipient;
uint256 targetGasReserveOverride;
bytes gatewaySettings;
}
/**
* @notice Token swap data structure
* @param fromAmount The quantity of the token
* @param routerType The numeric type of the swap router
* @param routerData The data for the swap router call
*/
struct SwapInfo {
uint256 fromAmount;
uint256 routerType;
bytes routerData;
}
/**
* @notice Cross-chain message data structure
* @param actionId The unique identifier of the cross-chain action
* @param sourceSender The address of the sender on the source chain
* @param gatewayType The numeric type of the gateway
* @param assetType The numeric type of the asset
* @param targetTokenAddress The address of the output token on the target chain
* @param targetSwapInfo The data for the target chain swap
* @param targetRecipient The address of the recipient on the target chain
* @param targetGasReserveOverride The target gas reserve override value
*/
struct TargetMessage {
uint256 actionId;
address sourceSender;
uint256 gatewayType;
uint256 assetType;
address targetTokenAddress;
SwapInfo targetSwapInfo;
address targetRecipient;
uint256 targetGasReserveOverride;
}
/**
* @notice Token amount data structure
* @param tokenAddress The address of the token
* @param amount The amount of the token
*/
struct TokenAmountData {
address tokenAddress;
uint256 amount;
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
/**
* @title IAssetDataStructures
* @notice Token data structure declarations
*/
interface IAssetDataStructures {
/**
* @notice Asset amount data structure
* @param assetType The type of the asset
* @param amount The amount of the asset
*/
struct AssetAmountData {
uint256 assetType;
uint256 amount;
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
import { ISettings } from './ISettings.sol';
interface IRegistry is ISettings {
/**
* @notice Getter of the registered gateway address by the gateway type
* @param _gatewayType The gateway type
* @return gatewayAddress The registered gateway address
*/
function gatewayMap(uint256 _gatewayType) external view returns (address gatewayAddress);
/**
* @notice Getter of source chain settings for a cross-chain swap
* @param _gatewayType The type of the cross-chain gateway
* @param _routerType The type of the swap router
* @return Source chain settings for a cross-chain swap
*/
function sourceSettings(
uint256 _gatewayType,
uint256 _routerType
) external view returns (SourceSettings memory);
/**
* @notice Getter of target chain settings for a cross-chain swap
* @param _routerType The type of the swap router
* @return Target chain settings for a cross-chain swap
*/
function targetSettings(uint256 _routerType) external view returns (TargetSettings memory);
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
/**
* @title ISettings
* @notice Settings data structure declarations
*/
interface ISettings {
/**
* @notice Source chain settings for a cross-chain swap
* @param gateway The cross-chain gateway contract address
* @param router The swap router contract address
* @param routerTransfer The swap router transfer contract address
*/
struct SourceSettings {
address gateway;
address router;
address routerTransfer;
}
/**
* @notice Target chain settings for a cross-chain swap
* @param router The swap router contract address
* @param routerTransfer The swap router transfer contract address
* @param gasReserve The target chain gas reserve value
*/
struct TargetSettings {
address router;
address routerTransfer;
uint256 gasReserve;
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
/**
* @title ITokenBalance
* @notice Token balance interface
*/
interface ITokenBalance {
/**
* @notice Getter of the token balance by the account
* @param _account The account address
* @return Token balance
*/
function balanceOf(address _account) external view returns (uint256);
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
import { Pausable as PausableBase } from '@openzeppelin/contracts/security/Pausable.sol';
import { ManagerRole } from './roles/ManagerRole.sol';
/**
* @title Pausable
* @notice Base contract that implements the emergency pause mechanism
*/
abstract contract Pausable is PausableBase, ManagerRole {
/**
* @notice Enter pause state
*/
function pause() external onlyManager whenNotPaused {
_pause();
}
/**
* @notice Exit pause state
*/
function unpause() external onlyManager whenPaused {
_unpause();
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
import { Ownable } from '@openzeppelin/contracts/access/Ownable.sol';
import { RoleBearers } from './RoleBearers.sol';
/**
* @title ManagerRole
* @notice Base contract that implements the Manager role.
* The manager role is a high-permission role for core team members only.
* Managers can set vaults and routers addresses, fees, cross-chain protocols,
* and other parameters for Interchain (cross-chain) swaps and single-network swaps.
* Please note, the manager role is unique for every contract,
* hence different addresses may be assigned as managers for different contracts.
*/
abstract contract ManagerRole is Ownable, RoleBearers {
bytes32 private constant ROLE_KEY = keccak256('Manager');
/**
* @notice Emitted when the Manager role status for the account is updated
* @param account The account address
* @param value The Manager role status flag
*/
event SetManager(address indexed account, bool indexed value);
/**
* @notice Emitted when the Manager role status for the account is renounced
* @param account The account address
*/
event RenounceManagerRole(address indexed account);
/**
* @notice Emitted when the caller is not a Manager role bearer
*/
error OnlyManagerError();
/**
* @dev Modifier to check if the caller is a Manager role bearer
*/
modifier onlyManager() {
if (!isManager(msg.sender)) {
revert OnlyManagerError();
}
_;
}
/**
* @notice Updates the Manager role status for the account
* @param _account The account address
* @param _value The Manager role status flag
*/
function setManager(address _account, bool _value) public onlyOwner {
_setRoleBearer(ROLE_KEY, _account, _value);
emit SetManager(_account, _value);
}
/**
* @notice Renounces the Manager role
*/
function renounceManagerRole() external onlyManager {
_setRoleBearer(ROLE_KEY, msg.sender, false);
emit RenounceManagerRole(msg.sender);
}
/**
* @notice Getter of the Manager role bearer count
* @return The Manager role bearer count
*/
function managerCount() external view returns (uint256) {
return _roleBearerCount(ROLE_KEY);
}
/**
* @notice Getter of the complete list of the Manager role bearers
* @return The complete list of the Manager role bearers
*/
function fullManagerList() external view returns (address[] memory) {
return _fullRoleBearerList(ROLE_KEY);
}
/**
* @notice Getter of the Manager role bearer status
* @param _account The account address
*/
function isManager(address _account) public view returns (bool) {
return _isRoleBearer(ROLE_KEY, _account);
}
function _initRoles(
address _owner,
address[] memory _managers,
bool _addOwnerToManagers
) internal {
address ownerAddress = _owner == address(0) ? msg.sender : _owner;
for (uint256 index; index < _managers.length; index++) {
setManager(_managers[index], true);
}
if (_addOwnerToManagers && !isManager(ownerAddress)) {
setManager(ownerAddress, true);
}
if (ownerAddress != msg.sender) {
transferOwnership(ownerAddress);
}
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
import '../Constants.sol' as Constants;
import '../DataStructures.sol' as DataStructures;
/**
* @title RoleBearers
* @notice Base contract that implements role-based access control
* @dev A custom implementation providing full role bearer lists
*/
abstract contract RoleBearers {
mapping(bytes32 /*roleKey*/ => address[] /*roleBearers*/) private roleBearerTable;
mapping(bytes32 /*roleKey*/ => mapping(address /*account*/ => DataStructures.OptionalValue /*status*/))
private roleBearerIndexTable;
function _setRoleBearer(bytes32 _roleKey, address _account, bool _value) internal {
DataStructures.uniqueAddressListUpdate(
roleBearerTable[_roleKey],
roleBearerIndexTable[_roleKey],
_account,
_value,
Constants.LIST_SIZE_LIMIT_DEFAULT
);
}
function _isRoleBearer(bytes32 _roleKey, address _account) internal view returns (bool) {
return roleBearerIndexTable[_roleKey][_account].isSet;
}
function _roleBearerCount(bytes32 _roleKey) internal view returns (uint256) {
return roleBearerTable[_roleKey].length;
}
function _fullRoleBearerList(bytes32 _roleKey) internal view returns (address[] memory) {
return roleBearerTable[_roleKey];
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.22;
/**
* @title SystemVersionId
* @notice Base contract providing the system version identifier
*/
abstract contract SystemVersionId {
/**
* @dev The system version identifier
*/
uint256 public constant SYSTEM_VERSION_ID = uint256(keccak256('Initial-2025-01-22'));
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IRegistry","name":"_registry","type":"address"},{"internalType":"uint256","name":"_actionIdOffset","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address[]","name":"_managers","type":"address[]"},{"internalType":"bool","name":"_addOwnerToManagers","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerGuardError","type":"error"},{"inputs":[],"name":"GatewayNotSetError","type":"error"},{"inputs":[],"name":"ListSizeLimitError","type":"error"},{"inputs":[],"name":"NativeTokenValueError","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NonContractAddressError","type":"error"},{"inputs":[],"name":"OnlyGatewayError","type":"error"},{"inputs":[],"name":"OnlyManagerError","type":"error"},{"inputs":[],"name":"OnlySelfError","type":"error"},{"inputs":[],"name":"ReservedTokenError","type":"error"},{"inputs":[],"name":"RouterNotSetError","type":"error"},{"inputs":[],"name":"SafeApproveError","type":"error"},{"inputs":[],"name":"SafeTransferError","type":"error"},{"inputs":[],"name":"SafeTransferFromError","type":"error"},{"inputs":[],"name":"SafeTransferNativeError","type":"error"},{"inputs":[],"name":"SameChainIdError","type":"error"},{"inputs":[],"name":"SwapError","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedAmount","type":"uint256"},{"internalType":"uint256","name":"actualAmount","type":"uint256"}],"name":"TargetAmountError","type":"error"},{"inputs":[],"name":"ZeroAddressError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"actionId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"targetChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sourceSender","type":"address"},{"indexed":false,"internalType":"address","name":"targetRecipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"gatewayType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assetType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"routerType","type":"uint256"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false,"internalType":"struct IActionDataStructures.TokenAmountData","name":"inputTokenAmountData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false,"internalType":"struct IActionDataStructures.TokenAmountData","name":"assetTokenAmountData","type":"tuple"},{"indexed":false,"internalType":"address","name":"targetToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"ActionSource","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"actionId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"sourceChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"gatewayType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assetType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"routerType","type":"uint256"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false,"internalType":"struct IActionDataStructures.TokenAmountData","name":"assetTokenAmountData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false,"internalType":"struct IActionDataStructures.TokenAmountData","name":"outputTokenAmountData","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"outputExtraAmount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isSuccess","type":"bool"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"ActionTarget","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"RenounceManagerRole","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum CallerGuard.CallerGuardMode","name":"callerGuardMode","type":"uint8"}],"name":"SetCallerGuardMode","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contractAddress","type":"address"},{"indexed":true,"internalType":"bool","name":"isListed","type":"bool"}],"name":"SetListedCallerGuardContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"bool","name":"value","type":"bool"}],"name":"SetManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"registryAddress","type":"address"}],"name":"SetRegistry","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"SYSTEM_VERSION_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callerGuardMode","outputs":[{"internalType":"enum CallerGuard.CallerGuardMode","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"cleanup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"gatewayType","type":"uint256"},{"internalType":"uint256","name":"assetType","type":"uint256"},{"internalType":"address","name":"sourceTokenAddress","type":"address"},{"components":[{"internalType":"uint256","name":"fromAmount","type":"uint256"},{"internalType":"uint256","name":"routerType","type":"uint256"},{"internalType":"bytes","name":"routerData","type":"bytes"}],"internalType":"struct IActionDataStructures.SwapInfo","name":"sourceSwapInfo","type":"tuple"},{"internalType":"uint256","name":"minTargetAmountLD","type":"uint256"},{"internalType":"uint256","name":"targetChainId","type":"uint256"},{"internalType":"address","name":"targetTokenAddress","type":"address"},{"components":[{"internalType":"uint256","name":"fromAmount","type":"uint256"},{"internalType":"uint256","name":"routerType","type":"uint256"},{"internalType":"bytes","name":"routerData","type":"bytes"}],"internalType":"struct IActionDataStructures.SwapInfo","name":"targetSwapInfo","type":"tuple"},{"internalType":"address","name":"targetRecipient","type":"address"},{"internalType":"uint256","name":"targetGasReserveOverride","type":"uint256"},{"internalType":"bytes","name":"gatewaySettings","type":"bytes"}],"internalType":"struct IActionDataStructures.Action","name":"_action","type":"tuple"}],"name":"execute","outputs":[{"internalType":"uint256","name":"actionId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"fullListedCallerGuardContractList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fullManagerList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_messageSourceChainId","type":"uint256"},{"internalType":"bytes","name":"_payloadData","type":"bytes"},{"internalType":"address","name":"_assetTokenAddress","type":"address"},{"internalType":"uint256","name":"_assetAmount","type":"uint256"}],"name":"handleExecutionPayload","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isListedCallerGuardContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isManager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"isReservedToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"listedCallerGuardContractCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"listedCallerGuardContractIndexMap","outputs":[{"internalType":"bool","name":"isSet","type":"bool"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"listedCallerGuardContractList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"managerCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"contract IRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceManagerRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"router","type":"address"},{"internalType":"address","name":"routerTransfer","type":"address"},{"internalType":"uint256","name":"gasReserve","type":"uint256"}],"internalType":"struct ISettings.TargetSettings","name":"_settings","type":"tuple"},{"components":[{"internalType":"uint256","name":"actionId","type":"uint256"},{"internalType":"address","name":"sourceSender","type":"address"},{"internalType":"uint256","name":"gatewayType","type":"uint256"},{"internalType":"uint256","name":"assetType","type":"uint256"},{"internalType":"address","name":"targetTokenAddress","type":"address"},{"components":[{"internalType":"uint256","name":"fromAmount","type":"uint256"},{"internalType":"uint256","name":"routerType","type":"uint256"},{"internalType":"bytes","name":"routerData","type":"bytes"}],"internalType":"struct IActionDataStructures.SwapInfo","name":"targetSwapInfo","type":"tuple"},{"internalType":"address","name":"targetRecipient","type":"address"},{"internalType":"uint256","name":"targetGasReserveOverride","type":"uint256"}],"internalType":"struct IActionDataStructures.TargetMessage","name":"_targetMessage","type":"tuple"},{"internalType":"address","name":"_fromTokenAddress","type":"address"}],"name":"selfCallTarget","outputs":[{"internalType":"uint256","name":"outputAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum CallerGuard.CallerGuardMode","name":"_callerGuardMode","type":"uint8"}],"name":"setCallerGuardMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"flag","type":"bool"}],"internalType":"struct AccountToFlag[]","name":"_items","type":"tuple[]"}],"name":"setListedCallerGuardContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bool","name":"_value","type":"bool"}],"name":"setManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IRegistry","name":"_registry","type":"address"}],"name":"setRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"tokenBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040526004805460ff191690556200001f4664174876e80062000658565b6200002f9063b7f6160962000672565b6008553480156200003f57600080fd5b50604051620034af380380620034af8339810160408190526200006291620006d7565b6000805460ff191690556200007733620000d5565b60016003556001600160a01b03851615620000975762000097856200012e565b8360086000828254620000ab919062000672565b90915550506004805460ff19166002179055620000ca83838362000183565b505050505062000836565b600080546001600160a01b03838116610100818102610100600160a81b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b620001398162000231565b600780546001600160a01b0319166001600160a01b0383169081179091556040517f278c70ced5f3e0e5eeb385b5ff9cb735748ba00a625147e66065ed48fc1562cd90600090a250565b60006001600160a01b038416156200019c57836200019e565b335b905060005b8351811015620001e557620001dc848281518110620001c657620001c6620007f4565b602002602001015160016200026d60201b60201c565b600101620001a3565b50818015620001fc5750620001fa81620002e0565b155b156200020f576200020f8160016200026d565b6001600160a01b03811633146200022b576200022b8162000322565b50505050565b6001600160a01b0381163b6200026a57604051638c50d7cd60e01b81526001600160a01b03821660048201526024015b60405180910390fd5b50565b620002776200039e565b620002a47f6d439300980e333f0256d64be2c9f67e86f4493ce25f82498d6db7f4be3d9e6f838362000402565b604051811515906001600160a01b038416907fbe9474bb3e78da7e315cdffa5cfa30b767fcc95bbf44a6197da60228eea1028690600090a35050565b6001600160a01b03811660009081527f260b29b219d450563ddb0e5ca806bdadb1e125f7e8c506de0443797dd7122728602052604081205460ff165b92915050565b6200032c6200039e565b6001600160a01b038116620003935760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000261565b6200026a81620000d5565b6000546001600160a01b03610100909104163314620004005760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000261565b565b600083815260016020908152604080832060029092529091206200022b91908484606460008262000440576200043a86868662000458565b6200044e565b6200044e868686856200058d565b9695505050505050565b6001600160a01b0381166000908152602083905260409020805460ff169081156200058557600180820154865490916000916200049691906200080a565b90508082146200052a576000878281548110620004b757620004b7620007f4565b9060005260206000200160009054906101000a90046001600160a01b0316905080888481548110620004ed57620004ed620007f4565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905592909116815290879052604090206001018290555b868054806200053d576200053d62000820565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b038716825287905260408120805460ff191681556001015550505b509392505050565b6001600160a01b03821660009081526020849052604090205460ff161580156200063a5784548211620005d35760405163b1655e3360e01b815260040160405180910390fd5b6040805180820182526001808252875460208084019182526001600160a01b03881660008181528a83529586209451855460ff1916901515178555915193830193909355885491820189558884529190922090910180546001600160a01b03191690911790555b949350505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176200031c576200031c62000642565b808201808211156200031c576200031c62000642565b6001600160a01b03811681146200026a57600080fd5b8051620006ab8162000688565b919050565b634e487b7160e01b600052604160045260246000fd5b80518015158114620006ab57600080fd5b600080600080600060a08688031215620006f057600080fd5b8551620006fd8162000688565b8095505060208087015194506040870151620007198162000688565b60608801519094506001600160401b03808211156200073757600080fd5b818901915089601f8301126200074c57600080fd5b815181811115620007615762000761620006b0565b8060051b604051601f19603f83011681018181108582111715620007895762000789620006b0565b60405291825284820192508381018501918c831115620007a857600080fd5b938501935b82851015620007d157620007c1856200069e565b84529385019392850192620007ad565b809750505050505050620007e860808701620006c6565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b818103818111156200031c576200031c62000642565b634e487b7160e01b600052603160045260246000fd5b612c6980620008466000396000f3fe6080604052600436106101bb5760003560e01c80637b103999116100ec578063e3725b151161008a578063f2fde38b11610064578063f2fde38b1461053a578063f3ae24151461055a578063f977350c1461057a578063fe14e8c31461059a57600080fd5b8063e3725b15146104f2578063e6c5c5d714610507578063eedc966a1461051a57600080fd5b80638da5cb5b116100c65780638da5cb5b1461047a578063a5e90eee1461049d578063a91ee0dc146104bd578063c2c518e1146104dd57600080fd5b80637b1039991461040d5780637b25b4d4146104455780638456cb591461046557600080fd5b80633f4ba83a116101595780636076f92a116101335780636076f92a146103a9578063607ab5e5146103bc5780636b56a691146103e3578063715018a6146103f857600080fd5b80633f4ba83a1461035b578063440d7248146103705780635c975abb1461039157600080fd5b806317daf0b41161019557806317daf0b41461027f5780632eaddd34146102c857806330eb1278146102e8578063341328c51461030a57600080fd5b806304e535e2146101c7578063093f0e27146101f2578063103b73971461023457600080fd5b366101c257005b600080fd5b3480156101d357600080fd5b506101dc6105ba565b6040516101e991906122a9565b60405180910390f35b3480156101fe57600080fd5b506102267fe322224f3a42a02485e6bbb933e62e967e91050cefd657687e5c2dc7bf9d04d381565b6040519081526020016101e9565b34801561024057600080fd5b50600080516020612c1483398151915260005260016020527f3c2285c553468ca8f30447b24bb463c127f1b840e23a0cafa23caa79d906669a54610226565b34801561028b57600080fd5b506102b861029a366004612316565b6001600160a01b031660009081526006602052604090205460ff1690565b60405190151581526020016101e9565b3480156102d457600080fd5b506102266102e3366004612333565b610621565b3480156102f457600080fd5b506103086103033660046123a3565b61069b565b005b34801561031657600080fd5b50610344610325366004612316565b6006602052600090815260409020805460019091015460ff9091169082565b6040805192151583526020830191909152016101e9565b34801561036757600080fd5b506103086106ff565b34801561037c57600080fd5b506102b861038b366004612316565b50600090565b34801561039d57600080fd5b5060005460ff166102b8565b6102266103b73660046123cf565b610737565b3480156103c857600080fd5b506004546103d69060ff1681565b6040516101e99190612421565b3480156103ef57600080fd5b50600554610226565b34801561040457600080fd5b50610308610c00565b34801561041957600080fd5b5060075461042d906001600160a01b031681565b6040516001600160a01b0390911681526020016101e9565b34801561045157600080fd5b5061042d610460366004612449565b610c12565b34801561047157600080fd5b50610308610c3c565b34801561048657600080fd5b5060005461010090046001600160a01b031661042d565b3480156104a957600080fd5b506103086104b8366004612470565b610c72565b3480156104c957600080fd5b506103086104d8366004612316565b610ccf565b3480156104e957600080fd5b50610308610d01565b3480156104fe57600080fd5b506101dc610d6e565b6103086105153660046124a9565b610d87565b34801561052657600080fd5b50610226610535366004612316565b611034565b34801561054657600080fd5b50610308610555366004612316565b6110d0565b34801561056657600080fd5b506102b8610575366004612316565b611146565b34801561058657600080fd5b50610308610595366004612540565b611186565b3480156105a657600080fd5b506103086105b5366004612561565b61120e565b6060600580548060200260200160405190810160405280929190818152602001828054801561061257602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116105f4575b5050505050905090565b905090565b6000333014610643576040516328a2ea3b60e01b815260040160405180910390fd5b6106916106553686900386018661266a565b8361066660a0870160808801612316565b61067360a08801886126b7565b61067c9061278a565b61068c60e0890160c08a01612316565b611315565b90505b9392505050565b6106a433611146565b6106c157604051637c3ea23f60e01b815260040160405180910390fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038316016106f4576106f03382611456565b5050565b6106f08233836114e4565b61070833611146565b61072557604051637c3ea23f60e01b815260040160405180910390fd5b61072d6115d6565b61073561161f565b565b6000610741611671565b6107496116b7565b3332146107d0576000600260045460ff16600281111561076b5761076b61240b565b14806107a75750600160045460ff16600281111561078b5761078b61240b565b1480156107a757503360009081526006602052604090205460ff165b9050806107ce57604051630fa0970d60e11b81523360048201526024015b60405180910390fd5b505b468260a00135036107f45760405163785a29dd60e01b815260040160405180910390fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6108196060840160408501612316565b6001600160a01b031614801561083b575061083760608301836126b7565b3534105b1561085957604051637dd7aa2160e01b815260040160405180910390fd5b600061086534476127ac565b600880549192506000610877836127bf565b90915550506008546007549092506000906001600160a01b031663619f42b785356108a560608801886126b7565b6040516001600160e01b031960e085901b1681526004810192909252602001356024820152604401606060405180830381865afa1580156108ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090e91906127d8565b80519091506001600160a01b03166109395760405163ba8ec24160e01b815260040160405180910390fd5b80516040516306833aa560e21b8152602086013560048201526000916001600160a01b031690631a0cea9490602401602060405180830381865afa158015610985573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a9919061282c565b90506001600160a01b0381166109d257604051633efa09af60e01b815260040160405180910390fd5b600080610a0e6109e86060890160408a01612316565b846109f660608b018b6126b7565b6109ff9061278a565b87602001518860400151611710565b6040805180820182526020808c0135825281018490528751915163d5c398db60e01b815293955091935090916000916001600160a01b03169063d5c398db90610a619060a08d0135908690600401612849565b602060405180830381865afa158015610a7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa29190612867565b90508860800135811015610ad6576040516303bdaee960e01b815260808a01356004820152602481018290526044016107c5565b60006040518061010001604052808a8152602001336001600160a01b031681526020018b6000013581526020018b6020013581526020018b60c0016020810190610b209190612316565b6001600160a01b03168152602001610b3b60e08d018d6126b7565b610b449061278a565b81526020016000610b5d6101208e016101008f01612316565b6001600160a01b031614610b8257610b7d6101208d016101008e01612316565b610b84565b335b6001600160a01b031681526101208c0135602091820152604051610ba992910161297a565b60408051601f198184030181529190529050610bd2878b83868a610bcd8a346127ac565b611988565b610bdd308933611a23565b610be9898b8888611a51565b5050505050505050610bfb6001600355565b919050565b610c08611b7a565b6107356000611bda565b60058181548110610c2257600080fd5b6000918252602090912001546001600160a01b0316905081565b610c4533611146565b610c6257604051637c3ea23f60e01b815260040160405180910390fd5b610c6a611671565b610735611c33565b610c7a611b7a565b610c93600080516020612c148339815191528383611c70565b604051811515906001600160a01b038416907fbe9474bb3e78da7e315cdffa5cfa30b767fcc95bbf44a6197da60228eea1028690600090a35050565b610cd833611146565b610cf557604051637c3ea23f60e01b815260040160405180910390fd5b610cfe81611c97565b50565b610d0a33611146565b610d2757604051637c3ea23f60e01b815260040160405180910390fd5b610d41600080516020612c14833981519152336000611c70565b60405133907f6cc2c67081f55c2fffb7c008fa995fbbf890f48c7c16fba93d8220f00dc84cc590600090a2565b606061061c600080516020612c14833981519152611cea565b610d8f611671565b6000610d9d8486018661298d565b6007546040828101519051631b8cb4f960e21b815260048101919091529192506001600160a01b031690636e32d3e490602401602060405180830381865afa158015610ded573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e11919061282c565b6001600160a01b0316336001600160a01b031614610e4257604051635d3da26d60e01b815260040160405180910390fd5b60a081015151821015610e795760a0810151516040516303bdaee960e01b81526004810191909152602481018390526044016107c5565b60075460a08201516020015160405163ae66aa7160e01b815260048101919091526000916001600160a01b03169063ae66aa7190602401606060405180830381865afa158015610ecd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef19190612a59565b9050610eff84333086611d56565b600080600080876001600160a01b031686608001516001600160a01b031603610f3057506001925085915081610ffe565b600080610f568860e00151600003610f4c578760400151611e51565b8860e00151611e51565b915091508115610fef57306001600160a01b0316632eaddd3482898b8e6040518563ffffffff1660e01b8152600401610f9193929190612aa6565b60206040518083038160008887f193505050508015610fcd575060408051601f3d908101601f19168201909252610fca91810190612867565b60015b15610fef5760a089015151600197509095508590610feb908b6127ac565b9450505b85610ff8578893505b83925050505b801561101357611013888760c00151836114e4565b6110278b878a8a8a6080015188888b611e7d565b5050505050505050505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b03831601611062575047919050565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa1580156110a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ca9190612867565b92915050565b6110d8611b7a565b6001600160a01b03811661113d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107c5565b610cfe81611bda565b6001600160a01b03811660009081527f260b29b219d450563ddb0e5ca806bdadb1e125f7e8c506de0443797dd7122728602052604081205460ff166110ca565b61118f33611146565b6111ac57604051637c3ea23f60e01b815260040160405180910390fd5b6004805482919060ff191660018360028111156111cb576111cb61240b565b02179055508060028111156111e2576111e261240b565b6040517f332a9f1d3bd9b0f7abbd95838fed6b417589632d0eb33f2d8ae6e2aa17178efd90600090a250565b61121733611146565b61123457604051637c3ea23f60e01b815260040160405180910390fd5b60005b81811015611310573683838381811061125257611252612af2565b905060400201905080602001602081019061126d9190612b08565b15611287576112876112826020830183612316565b611f84565b6112b26005600661129b6020850185612316565b6112ab6040860160208701612b08565b6064611fb7565b506112c36040820160208301612b08565b15156112d26020830183612316565b6001600160a01b03167f1470aed653fa8a8ce4c7b2f41287634199f7ec3c4f5fd0ace97d82cf006beec360405160405180910390a350600101611237565b505050565b84516000906001600160a01b03166113405760405163ebb12eb360e01b815260040160405180910390fd5b600061134b85611034565b90506113608688602001518660000151611fe4565b600087600001516001600160a01b031685604001516040516113829190612b25565b6000604051808303816000865af19150503d80600081146113bf576040519150601f19603f3d011682016040523d82523d6000602084013e6113c4565b606091505b50509050806113e657604051633e1f5ce560e11b815260040160405180910390fd5b6113f68789602001516000611fe4565b8161140087611034565b61140a91906127ac565b925073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038716016114405761143b8484611456565b61144b565b61144b8685856114e4565b505095945050505050565b604080516000808252602082019092526001600160a01b0384169083906040516114809190612b25565b60006040518083038185875af1925050503d80600081146114bd576040519150601f19603f3d011682016040523d82523d6000602084013e6114c2565b606091505b505090508061131057604051632e05b05360e21b815260040160405180910390fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916115409190612b25565b6000604051808303816000865af19150503d806000811461157d576040519150601f19603f3d011682016040523d82523d6000602084013e611582565b606091505b509150915060008280156115ae5750815115806115ae5750818060200190518101906115ae9190612b37565b9050806115ce57604051632fdb1b7f60e11b815260040160405180910390fd5b505050505050565b60005460ff166107355760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016107c5565b6116276115d6565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60005460ff16156107355760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016107c5565b6002600354036117095760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107c5565b6002600355565b60008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038816016118465773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b0387160161176757505082518061197e565b600061177287611034565b90506001600160a01b03851661179b5760405163ebb12eb360e01b815260040160405180910390fd5b6000856001600160a01b0316876000015188604001516040516117be9190612b25565b60006040518083038185875af1925050503d80600081146117fb576040519150601f19603f3d011682016040523d82523d6000602084013e611800565b606091505b505090508061182257604051633e1f5ce560e11b815260040160405180910390fd5b8161182c89611034565b61183691906127ac565b935086600001519250505061197e565b856001600160a01b0316876001600160a01b03161415801561186f57506001600160a01b038416155b1561188d5760405163ebb12eb360e01b815260040160405180910390fd5b600061189887611034565b90506118aa8833308960000151611d56565b866001600160a01b0316886001600160a01b031614611962576118d288858860000151611fe4565b6000856001600160a01b031687604001516040516118f09190612b25565b6000604051808303816000865af19150503d806000811461192d576040519150601f19603f3d011682016040523d82523d6000602084013e611932565b606091505b505090508061195457604051633e1f5ce560e11b815260040160405180910390fd5b61196089866000611fe4565b505b8061196c88611034565b61197691906127ac565b925060009150505b9550959350505050565b61199b8287600001518560200151611fe4565b85516001600160a01b031663fbef03238260a0880135876119c06101408b018b612b54565b896040518763ffffffff1660e01b81526004016119e1959493929190612ba2565b6000604051808303818588803b1580156119fa57600080fd5b505af1158015611a0e573d6000803e3d6000fd5b50505050506115ce8287600001516000611fe4565b6000611a39836001600160a01b038616316127ac565b90508015611a4b57611a4b8282611456565b50505050565b3360a0840135857f89477d47752398865f4821cbf8ee5881f451b62209b16656f0888886f321f05e611a8b61012088016101008901612316565b87356020890135611a9f60608b018b6126b7565b6020013560405180604001604052808c6040016020810190611ac19190612316565b6001600160a01b03168152602001611adc60608e018e6126b7565b359052604080518082019091526001600160a01b038c168152602081018b9052611b0c60e08e0160c08f01612316565b604080516001600160a01b0398891681526020808201989098529081019590955260608501939093528151861660808501529084015160a08401528051851660c08401529092015160e08201529116610100820152426101208201526101400160405180910390a450505050565b6000546001600160a01b036101009091041633146107355760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107c5565b600080546001600160a01b03838116610100818102610100600160a81b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b611c3b611671565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586116543390565b60008381526001602090815260408083206002909252909120611a4b919084846064611fb7565b611ca081611f84565b600780546001600160a01b0319166001600160a01b0383169081179091556040517f278c70ced5f3e0e5eeb385b5ff9cb735748ba00a625147e66065ed48fc1562cd90600090a250565b600081815260016020908152604091829020805483518184028101840190945280845260609392830182828015611d4a57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611d2c575b50505050509050919050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691611dba9190612b25565b6000604051808303816000865af19150503d8060008114611df7576040519150601f19603f3d011682016040523d82523d6000602084013e611dfc565b606091505b50915091506000828015611e28575081511580611e28575081806020019051810190611e289190612b37565b905080611e4857604051632d9d5b4160e01b815260040160405180910390fd5b50505050505050565b60008060005a905083811015925082611e6b576000611e75565b611e7584826127ac565b915050915091565b8660c001516001600160a01b03168888600001517f0c50da7f46b12ae11adb367707e3ffeb5654054c4ce154789265ef706cec200c8a604001518b606001518c60a001516020015160405180604001604052808e6001600160a01b031681526020018d81525060405180604001604052808d6001600160a01b031681526020018c8152508a8a42604051611f72989796959493929190978852602080890197909752604088019590955283516001600160a01b039081166060890152938601516080880152825190931660a087015293015160c085015260e08401929092529015156101008301526101208201526101400190565b60405180910390a45050505050505050565b6001600160a01b0381163b610cfe57604051638c50d7cd60e01b81526001600160a01b03821660048201526024016107c5565b600082611fce57611fc98686866120ce565b611fda565b611fda868686856121f6565b9695505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291516000928392908716916120409190612b25565b6000604051808303816000865af19150503d806000811461207d576040519150601f19603f3d011682016040523d82523d6000602084013e612082565b606091505b509150915060008280156120ae5750815115806120ae5750818060200190518101906120ae9190612b37565b9050806115ce5760405163b45d44e760e01b815260040160405180910390fd5b6001600160a01b0381166000908152602083905260409020805460ff169081156121ee576001808201548654909160009161210991906127ac565b905080821461219657600087828154811061212657612126612af2565b9060005260206000200160009054906101000a90046001600160a01b031690508088848154811061215957612159612af2565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905592909116815290879052604090206001018290555b868054806121a6576121a6612bfd565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b038716825287905260408120805460ff191681556001015550505b509392505050565b6001600160a01b03821660009081526020849052604090205460ff161580156122a1578454821161223a5760405163b1655e3360e01b815260040160405180910390fd5b6040805180820182526001808252875460208084019182526001600160a01b03881660008181528a83529586209451855460ff1916901515178555915193830193909355885491820189558884529190922090910180546001600160a01b03191690911790555b949350505050565b6020808252825182820181905260009190848201906040850190845b818110156122ea5783516001600160a01b0316835292840192918401916001016122c5565b50909695505050505050565b6001600160a01b0381168114610cfe57600080fd5b8035610bfb816122f6565b60006020828403121561232857600080fd5b8135610694816122f6565b600080600083850360a081121561234957600080fd5b606081121561235757600080fd5b50839250606084013567ffffffffffffffff81111561237557600080fd5b8401610100818703121561238857600080fd5b91506080840135612398816122f6565b809150509250925092565b600080604083850312156123b657600080fd5b82356123c1816122f6565b946020939093013593505050565b6000602082840312156123e157600080fd5b813567ffffffffffffffff8111156123f857600080fd5b8201610160818503121561069457600080fd5b634e487b7160e01b600052602160045260246000fd5b602081016003831061244357634e487b7160e01b600052602160045260246000fd5b91905290565b60006020828403121561245b57600080fd5b5035919050565b8015158114610cfe57600080fd5b6000806040838503121561248357600080fd5b823561248e816122f6565b9150602083013561249e81612462565b809150509250929050565b6000806000806000608086880312156124c157600080fd5b85359450602086013567ffffffffffffffff808211156124e057600080fd5b818801915088601f8301126124f457600080fd5b81358181111561250357600080fd5b89602082850101111561251557600080fd5b602083019650809550505050604086013561252f816122f6565b949793965091946060013592915050565b60006020828403121561255257600080fd5b81356003811061069457600080fd5b6000806020838503121561257457600080fd5b823567ffffffffffffffff8082111561258c57600080fd5b818501915085601f8301126125a057600080fd5b8135818111156125af57600080fd5b8660208260061b85010111156125c457600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561260f5761260f6125d6565b60405290565b604051610100810167ffffffffffffffff8111828210171561260f5761260f6125d6565b604051601f8201601f1916810167ffffffffffffffff81118282101715612662576126626125d6565b604052919050565b60006060828403121561267c57600080fd5b6126846125ec565b823561268f816122f6565b8152602083013561269f816122f6565b60208201526040928301359281019290925250919050565b60008235605e198336030181126126cd57600080fd5b9190910192915050565b6000606082840312156126e957600080fd5b6126f16125ec565b90508135815260208083013581830152604083013567ffffffffffffffff8082111561271c57600080fd5b818501915085601f83011261273057600080fd5b813581811115612742576127426125d6565b612754601f8201601f19168501612639565b9150808252868482850101111561276a57600080fd5b808484018584013760008482840101525080604085015250505092915050565b60006110ca36836126d7565b634e487b7160e01b600052601160045260246000fd5b818103818111156110ca576110ca612796565b6000600182016127d1576127d1612796565b5060010190565b6000606082840312156127ea57600080fd5b6127f26125ec565b82516127fd816122f6565b8152602083015161280d816122f6565b60208201526040830151612820816122f6565b60408201529392505050565b60006020828403121561283e57600080fd5b8151610694816122f6565b82815260608101610694602083018480518252602090810151910152565b60006020828403121561287957600080fd5b5051919050565b60005b8381101561289b578181015183820152602001612883565b50506000910152565b600081518084526128bc816020860160208601612880565b601f01601f19169290920160200192915050565b600061010082518452602083015160018060a01b0380821660208701526040850151604087015260608501516060870152806080860151166080870152505060a08301518160a08601528051828601526020810151610120860152604081015191505060606101408501526129496101608501826128a4565b905060c083015161296560c08601826001600160a01b03169052565b5060e083015160e08501528091505092915050565b60208152600061069460208301846128d0565b60006020828403121561299f57600080fd5b813567ffffffffffffffff808211156129b757600080fd5b9083019061010082860312156129cc57600080fd5b6129d4612615565b823581526129e46020840161230b565b60208201526040830135604082015260608301356060820152612a096080840161230b565b608082015260a083013582811115612a2057600080fd5b612a2c878286016126d7565b60a083015250612a3e60c0840161230b565b60c082015260e083013560e082015280935050505092915050565b600060608284031215612a6b57600080fd5b612a736125ec565b8251612a7e816122f6565b81526020830151612a8e816122f6565b60208201526040928301519281019290925250919050565b600060018060a01b038086511683528060208701511660208401526040860151604084015260a06060840152612adf60a08401866128d0565b9150808416608084015250949350505050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612b1a57600080fd5b813561069481612462565b600082516126cd818460208701612880565b600060208284031215612b4957600080fd5b815161069481612462565b6000808335601e19843603018112612b6b57600080fd5b83018035915067ffffffffffffffff821115612b8657600080fd5b602001915036819003821315612b9b57600080fd5b9250929050565b85815260a060208201526000612bbb60a08301876128a4565b8281036040840152848152848660208301376000602086830101526020601f19601f870116820101915050611fda606083018480518252602090810151910152565b634e487b7160e01b600052603160045260246000fdfe6d439300980e333f0256d64be2c9f67e86f4493ce25f82498d6db7f4be3d9e6fa26469706673582212207618a3a0388d1529251f39c1ac32bb8b809302c9c89c2429b9ddf075b9282cdb64736f6c634300081600330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072e28c7f34100afefc399fcc0ae041b8fe5841ae00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101bb5760003560e01c80637b103999116100ec578063e3725b151161008a578063f2fde38b11610064578063f2fde38b1461053a578063f3ae24151461055a578063f977350c1461057a578063fe14e8c31461059a57600080fd5b8063e3725b15146104f2578063e6c5c5d714610507578063eedc966a1461051a57600080fd5b80638da5cb5b116100c65780638da5cb5b1461047a578063a5e90eee1461049d578063a91ee0dc146104bd578063c2c518e1146104dd57600080fd5b80637b1039991461040d5780637b25b4d4146104455780638456cb591461046557600080fd5b80633f4ba83a116101595780636076f92a116101335780636076f92a146103a9578063607ab5e5146103bc5780636b56a691146103e3578063715018a6146103f857600080fd5b80633f4ba83a1461035b578063440d7248146103705780635c975abb1461039157600080fd5b806317daf0b41161019557806317daf0b41461027f5780632eaddd34146102c857806330eb1278146102e8578063341328c51461030a57600080fd5b806304e535e2146101c7578063093f0e27146101f2578063103b73971461023457600080fd5b366101c257005b600080fd5b3480156101d357600080fd5b506101dc6105ba565b6040516101e991906122a9565b60405180910390f35b3480156101fe57600080fd5b506102267fe322224f3a42a02485e6bbb933e62e967e91050cefd657687e5c2dc7bf9d04d381565b6040519081526020016101e9565b34801561024057600080fd5b50600080516020612c1483398151915260005260016020527f3c2285c553468ca8f30447b24bb463c127f1b840e23a0cafa23caa79d906669a54610226565b34801561028b57600080fd5b506102b861029a366004612316565b6001600160a01b031660009081526006602052604090205460ff1690565b60405190151581526020016101e9565b3480156102d457600080fd5b506102266102e3366004612333565b610621565b3480156102f457600080fd5b506103086103033660046123a3565b61069b565b005b34801561031657600080fd5b50610344610325366004612316565b6006602052600090815260409020805460019091015460ff9091169082565b6040805192151583526020830191909152016101e9565b34801561036757600080fd5b506103086106ff565b34801561037c57600080fd5b506102b861038b366004612316565b50600090565b34801561039d57600080fd5b5060005460ff166102b8565b6102266103b73660046123cf565b610737565b3480156103c857600080fd5b506004546103d69060ff1681565b6040516101e99190612421565b3480156103ef57600080fd5b50600554610226565b34801561040457600080fd5b50610308610c00565b34801561041957600080fd5b5060075461042d906001600160a01b031681565b6040516001600160a01b0390911681526020016101e9565b34801561045157600080fd5b5061042d610460366004612449565b610c12565b34801561047157600080fd5b50610308610c3c565b34801561048657600080fd5b5060005461010090046001600160a01b031661042d565b3480156104a957600080fd5b506103086104b8366004612470565b610c72565b3480156104c957600080fd5b506103086104d8366004612316565b610ccf565b3480156104e957600080fd5b50610308610d01565b3480156104fe57600080fd5b506101dc610d6e565b6103086105153660046124a9565b610d87565b34801561052657600080fd5b50610226610535366004612316565b611034565b34801561054657600080fd5b50610308610555366004612316565b6110d0565b34801561056657600080fd5b506102b8610575366004612316565b611146565b34801561058657600080fd5b50610308610595366004612540565b611186565b3480156105a657600080fd5b506103086105b5366004612561565b61120e565b6060600580548060200260200160405190810160405280929190818152602001828054801561061257602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116105f4575b5050505050905090565b905090565b6000333014610643576040516328a2ea3b60e01b815260040160405180910390fd5b6106916106553686900386018661266a565b8361066660a0870160808801612316565b61067360a08801886126b7565b61067c9061278a565b61068c60e0890160c08a01612316565b611315565b90505b9392505050565b6106a433611146565b6106c157604051637c3ea23f60e01b815260040160405180910390fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038316016106f4576106f03382611456565b5050565b6106f08233836114e4565b61070833611146565b61072557604051637c3ea23f60e01b815260040160405180910390fd5b61072d6115d6565b61073561161f565b565b6000610741611671565b6107496116b7565b3332146107d0576000600260045460ff16600281111561076b5761076b61240b565b14806107a75750600160045460ff16600281111561078b5761078b61240b565b1480156107a757503360009081526006602052604090205460ff165b9050806107ce57604051630fa0970d60e11b81523360048201526024015b60405180910390fd5b505b468260a00135036107f45760405163785a29dd60e01b815260040160405180910390fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6108196060840160408501612316565b6001600160a01b031614801561083b575061083760608301836126b7565b3534105b1561085957604051637dd7aa2160e01b815260040160405180910390fd5b600061086534476127ac565b600880549192506000610877836127bf565b90915550506008546007549092506000906001600160a01b031663619f42b785356108a560608801886126b7565b6040516001600160e01b031960e085901b1681526004810192909252602001356024820152604401606060405180830381865afa1580156108ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090e91906127d8565b80519091506001600160a01b03166109395760405163ba8ec24160e01b815260040160405180910390fd5b80516040516306833aa560e21b8152602086013560048201526000916001600160a01b031690631a0cea9490602401602060405180830381865afa158015610985573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a9919061282c565b90506001600160a01b0381166109d257604051633efa09af60e01b815260040160405180910390fd5b600080610a0e6109e86060890160408a01612316565b846109f660608b018b6126b7565b6109ff9061278a565b87602001518860400151611710565b6040805180820182526020808c0135825281018490528751915163d5c398db60e01b815293955091935090916000916001600160a01b03169063d5c398db90610a619060a08d0135908690600401612849565b602060405180830381865afa158015610a7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa29190612867565b90508860800135811015610ad6576040516303bdaee960e01b815260808a01356004820152602481018290526044016107c5565b60006040518061010001604052808a8152602001336001600160a01b031681526020018b6000013581526020018b6020013581526020018b60c0016020810190610b209190612316565b6001600160a01b03168152602001610b3b60e08d018d6126b7565b610b449061278a565b81526020016000610b5d6101208e016101008f01612316565b6001600160a01b031614610b8257610b7d6101208d016101008e01612316565b610b84565b335b6001600160a01b031681526101208c0135602091820152604051610ba992910161297a565b60408051601f198184030181529190529050610bd2878b83868a610bcd8a346127ac565b611988565b610bdd308933611a23565b610be9898b8888611a51565b5050505050505050610bfb6001600355565b919050565b610c08611b7a565b6107356000611bda565b60058181548110610c2257600080fd5b6000918252602090912001546001600160a01b0316905081565b610c4533611146565b610c6257604051637c3ea23f60e01b815260040160405180910390fd5b610c6a611671565b610735611c33565b610c7a611b7a565b610c93600080516020612c148339815191528383611c70565b604051811515906001600160a01b038416907fbe9474bb3e78da7e315cdffa5cfa30b767fcc95bbf44a6197da60228eea1028690600090a35050565b610cd833611146565b610cf557604051637c3ea23f60e01b815260040160405180910390fd5b610cfe81611c97565b50565b610d0a33611146565b610d2757604051637c3ea23f60e01b815260040160405180910390fd5b610d41600080516020612c14833981519152336000611c70565b60405133907f6cc2c67081f55c2fffb7c008fa995fbbf890f48c7c16fba93d8220f00dc84cc590600090a2565b606061061c600080516020612c14833981519152611cea565b610d8f611671565b6000610d9d8486018661298d565b6007546040828101519051631b8cb4f960e21b815260048101919091529192506001600160a01b031690636e32d3e490602401602060405180830381865afa158015610ded573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e11919061282c565b6001600160a01b0316336001600160a01b031614610e4257604051635d3da26d60e01b815260040160405180910390fd5b60a081015151821015610e795760a0810151516040516303bdaee960e01b81526004810191909152602481018390526044016107c5565b60075460a08201516020015160405163ae66aa7160e01b815260048101919091526000916001600160a01b03169063ae66aa7190602401606060405180830381865afa158015610ecd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef19190612a59565b9050610eff84333086611d56565b600080600080876001600160a01b031686608001516001600160a01b031603610f3057506001925085915081610ffe565b600080610f568860e00151600003610f4c578760400151611e51565b8860e00151611e51565b915091508115610fef57306001600160a01b0316632eaddd3482898b8e6040518563ffffffff1660e01b8152600401610f9193929190612aa6565b60206040518083038160008887f193505050508015610fcd575060408051601f3d908101601f19168201909252610fca91810190612867565b60015b15610fef5760a089015151600197509095508590610feb908b6127ac565b9450505b85610ff8578893505b83925050505b801561101357611013888760c00151836114e4565b6110278b878a8a8a6080015188888b611e7d565b5050505050505050505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b03831601611062575047919050565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa1580156110a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ca9190612867565b92915050565b6110d8611b7a565b6001600160a01b03811661113d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107c5565b610cfe81611bda565b6001600160a01b03811660009081527f260b29b219d450563ddb0e5ca806bdadb1e125f7e8c506de0443797dd7122728602052604081205460ff166110ca565b61118f33611146565b6111ac57604051637c3ea23f60e01b815260040160405180910390fd5b6004805482919060ff191660018360028111156111cb576111cb61240b565b02179055508060028111156111e2576111e261240b565b6040517f332a9f1d3bd9b0f7abbd95838fed6b417589632d0eb33f2d8ae6e2aa17178efd90600090a250565b61121733611146565b61123457604051637c3ea23f60e01b815260040160405180910390fd5b60005b81811015611310573683838381811061125257611252612af2565b905060400201905080602001602081019061126d9190612b08565b15611287576112876112826020830183612316565b611f84565b6112b26005600661129b6020850185612316565b6112ab6040860160208701612b08565b6064611fb7565b506112c36040820160208301612b08565b15156112d26020830183612316565b6001600160a01b03167f1470aed653fa8a8ce4c7b2f41287634199f7ec3c4f5fd0ace97d82cf006beec360405160405180910390a350600101611237565b505050565b84516000906001600160a01b03166113405760405163ebb12eb360e01b815260040160405180910390fd5b600061134b85611034565b90506113608688602001518660000151611fe4565b600087600001516001600160a01b031685604001516040516113829190612b25565b6000604051808303816000865af19150503d80600081146113bf576040519150601f19603f3d011682016040523d82523d6000602084013e6113c4565b606091505b50509050806113e657604051633e1f5ce560e11b815260040160405180910390fd5b6113f68789602001516000611fe4565b8161140087611034565b61140a91906127ac565b925073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038716016114405761143b8484611456565b61144b565b61144b8685856114e4565b505095945050505050565b604080516000808252602082019092526001600160a01b0384169083906040516114809190612b25565b60006040518083038185875af1925050503d80600081146114bd576040519150601f19603f3d011682016040523d82523d6000602084013e6114c2565b606091505b505090508061131057604051632e05b05360e21b815260040160405180910390fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916115409190612b25565b6000604051808303816000865af19150503d806000811461157d576040519150601f19603f3d011682016040523d82523d6000602084013e611582565b606091505b509150915060008280156115ae5750815115806115ae5750818060200190518101906115ae9190612b37565b9050806115ce57604051632fdb1b7f60e11b815260040160405180910390fd5b505050505050565b60005460ff166107355760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016107c5565b6116276115d6565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60005460ff16156107355760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016107c5565b6002600354036117095760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107c5565b6002600355565b60008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038816016118465773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b0387160161176757505082518061197e565b600061177287611034565b90506001600160a01b03851661179b5760405163ebb12eb360e01b815260040160405180910390fd5b6000856001600160a01b0316876000015188604001516040516117be9190612b25565b60006040518083038185875af1925050503d80600081146117fb576040519150601f19603f3d011682016040523d82523d6000602084013e611800565b606091505b505090508061182257604051633e1f5ce560e11b815260040160405180910390fd5b8161182c89611034565b61183691906127ac565b935086600001519250505061197e565b856001600160a01b0316876001600160a01b03161415801561186f57506001600160a01b038416155b1561188d5760405163ebb12eb360e01b815260040160405180910390fd5b600061189887611034565b90506118aa8833308960000151611d56565b866001600160a01b0316886001600160a01b031614611962576118d288858860000151611fe4565b6000856001600160a01b031687604001516040516118f09190612b25565b6000604051808303816000865af19150503d806000811461192d576040519150601f19603f3d011682016040523d82523d6000602084013e611932565b606091505b505090508061195457604051633e1f5ce560e11b815260040160405180910390fd5b61196089866000611fe4565b505b8061196c88611034565b61197691906127ac565b925060009150505b9550959350505050565b61199b8287600001518560200151611fe4565b85516001600160a01b031663fbef03238260a0880135876119c06101408b018b612b54565b896040518763ffffffff1660e01b81526004016119e1959493929190612ba2565b6000604051808303818588803b1580156119fa57600080fd5b505af1158015611a0e573d6000803e3d6000fd5b50505050506115ce8287600001516000611fe4565b6000611a39836001600160a01b038616316127ac565b90508015611a4b57611a4b8282611456565b50505050565b3360a0840135857f89477d47752398865f4821cbf8ee5881f451b62209b16656f0888886f321f05e611a8b61012088016101008901612316565b87356020890135611a9f60608b018b6126b7565b6020013560405180604001604052808c6040016020810190611ac19190612316565b6001600160a01b03168152602001611adc60608e018e6126b7565b359052604080518082019091526001600160a01b038c168152602081018b9052611b0c60e08e0160c08f01612316565b604080516001600160a01b0398891681526020808201989098529081019590955260608501939093528151861660808501529084015160a08401528051851660c08401529092015160e08201529116610100820152426101208201526101400160405180910390a450505050565b6000546001600160a01b036101009091041633146107355760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107c5565b600080546001600160a01b03838116610100818102610100600160a81b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b611c3b611671565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586116543390565b60008381526001602090815260408083206002909252909120611a4b919084846064611fb7565b611ca081611f84565b600780546001600160a01b0319166001600160a01b0383169081179091556040517f278c70ced5f3e0e5eeb385b5ff9cb735748ba00a625147e66065ed48fc1562cd90600090a250565b600081815260016020908152604091829020805483518184028101840190945280845260609392830182828015611d4a57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611d2c575b50505050509050919050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691611dba9190612b25565b6000604051808303816000865af19150503d8060008114611df7576040519150601f19603f3d011682016040523d82523d6000602084013e611dfc565b606091505b50915091506000828015611e28575081511580611e28575081806020019051810190611e289190612b37565b905080611e4857604051632d9d5b4160e01b815260040160405180910390fd5b50505050505050565b60008060005a905083811015925082611e6b576000611e75565b611e7584826127ac565b915050915091565b8660c001516001600160a01b03168888600001517f0c50da7f46b12ae11adb367707e3ffeb5654054c4ce154789265ef706cec200c8a604001518b606001518c60a001516020015160405180604001604052808e6001600160a01b031681526020018d81525060405180604001604052808d6001600160a01b031681526020018c8152508a8a42604051611f72989796959493929190978852602080890197909752604088019590955283516001600160a01b039081166060890152938601516080880152825190931660a087015293015160c085015260e08401929092529015156101008301526101208201526101400190565b60405180910390a45050505050505050565b6001600160a01b0381163b610cfe57604051638c50d7cd60e01b81526001600160a01b03821660048201526024016107c5565b600082611fce57611fc98686866120ce565b611fda565b611fda868686856121f6565b9695505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291516000928392908716916120409190612b25565b6000604051808303816000865af19150503d806000811461207d576040519150601f19603f3d011682016040523d82523d6000602084013e612082565b606091505b509150915060008280156120ae5750815115806120ae5750818060200190518101906120ae9190612b37565b9050806115ce5760405163b45d44e760e01b815260040160405180910390fd5b6001600160a01b0381166000908152602083905260409020805460ff169081156121ee576001808201548654909160009161210991906127ac565b905080821461219657600087828154811061212657612126612af2565b9060005260206000200160009054906101000a90046001600160a01b031690508088848154811061215957612159612af2565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905592909116815290879052604090206001018290555b868054806121a6576121a6612bfd565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b038716825287905260408120805460ff191681556001015550505b509392505050565b6001600160a01b03821660009081526020849052604090205460ff161580156122a1578454821161223a5760405163b1655e3360e01b815260040160405180910390fd5b6040805180820182526001808252875460208084019182526001600160a01b03881660008181528a83529586209451855460ff1916901515178555915193830193909355885491820189558884529190922090910180546001600160a01b03191690911790555b949350505050565b6020808252825182820181905260009190848201906040850190845b818110156122ea5783516001600160a01b0316835292840192918401916001016122c5565b50909695505050505050565b6001600160a01b0381168114610cfe57600080fd5b8035610bfb816122f6565b60006020828403121561232857600080fd5b8135610694816122f6565b600080600083850360a081121561234957600080fd5b606081121561235757600080fd5b50839250606084013567ffffffffffffffff81111561237557600080fd5b8401610100818703121561238857600080fd5b91506080840135612398816122f6565b809150509250925092565b600080604083850312156123b657600080fd5b82356123c1816122f6565b946020939093013593505050565b6000602082840312156123e157600080fd5b813567ffffffffffffffff8111156123f857600080fd5b8201610160818503121561069457600080fd5b634e487b7160e01b600052602160045260246000fd5b602081016003831061244357634e487b7160e01b600052602160045260246000fd5b91905290565b60006020828403121561245b57600080fd5b5035919050565b8015158114610cfe57600080fd5b6000806040838503121561248357600080fd5b823561248e816122f6565b9150602083013561249e81612462565b809150509250929050565b6000806000806000608086880312156124c157600080fd5b85359450602086013567ffffffffffffffff808211156124e057600080fd5b818801915088601f8301126124f457600080fd5b81358181111561250357600080fd5b89602082850101111561251557600080fd5b602083019650809550505050604086013561252f816122f6565b949793965091946060013592915050565b60006020828403121561255257600080fd5b81356003811061069457600080fd5b6000806020838503121561257457600080fd5b823567ffffffffffffffff8082111561258c57600080fd5b818501915085601f8301126125a057600080fd5b8135818111156125af57600080fd5b8660208260061b85010111156125c457600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561260f5761260f6125d6565b60405290565b604051610100810167ffffffffffffffff8111828210171561260f5761260f6125d6565b604051601f8201601f1916810167ffffffffffffffff81118282101715612662576126626125d6565b604052919050565b60006060828403121561267c57600080fd5b6126846125ec565b823561268f816122f6565b8152602083013561269f816122f6565b60208201526040928301359281019290925250919050565b60008235605e198336030181126126cd57600080fd5b9190910192915050565b6000606082840312156126e957600080fd5b6126f16125ec565b90508135815260208083013581830152604083013567ffffffffffffffff8082111561271c57600080fd5b818501915085601f83011261273057600080fd5b813581811115612742576127426125d6565b612754601f8201601f19168501612639565b9150808252868482850101111561276a57600080fd5b808484018584013760008482840101525080604085015250505092915050565b60006110ca36836126d7565b634e487b7160e01b600052601160045260246000fd5b818103818111156110ca576110ca612796565b6000600182016127d1576127d1612796565b5060010190565b6000606082840312156127ea57600080fd5b6127f26125ec565b82516127fd816122f6565b8152602083015161280d816122f6565b60208201526040830151612820816122f6565b60408201529392505050565b60006020828403121561283e57600080fd5b8151610694816122f6565b82815260608101610694602083018480518252602090810151910152565b60006020828403121561287957600080fd5b5051919050565b60005b8381101561289b578181015183820152602001612883565b50506000910152565b600081518084526128bc816020860160208601612880565b601f01601f19169290920160200192915050565b600061010082518452602083015160018060a01b0380821660208701526040850151604087015260608501516060870152806080860151166080870152505060a08301518160a08601528051828601526020810151610120860152604081015191505060606101408501526129496101608501826128a4565b905060c083015161296560c08601826001600160a01b03169052565b5060e083015160e08501528091505092915050565b60208152600061069460208301846128d0565b60006020828403121561299f57600080fd5b813567ffffffffffffffff808211156129b757600080fd5b9083019061010082860312156129cc57600080fd5b6129d4612615565b823581526129e46020840161230b565b60208201526040830135604082015260608301356060820152612a096080840161230b565b608082015260a083013582811115612a2057600080fd5b612a2c878286016126d7565b60a083015250612a3e60c0840161230b565b60c082015260e083013560e082015280935050505092915050565b600060608284031215612a6b57600080fd5b612a736125ec565b8251612a7e816122f6565b81526020830151612a8e816122f6565b60208201526040928301519281019290925250919050565b600060018060a01b038086511683528060208701511660208401526040860151604084015260a06060840152612adf60a08401866128d0565b9150808416608084015250949350505050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612b1a57600080fd5b813561069481612462565b600082516126cd818460208701612880565b600060208284031215612b4957600080fd5b815161069481612462565b6000808335601e19843603018112612b6b57600080fd5b83018035915067ffffffffffffffff821115612b8657600080fd5b602001915036819003821315612b9b57600080fd5b9250929050565b85815260a060208201526000612bbb60a08301876128a4565b8281036040840152848152848660208301376000602086830101526020601f19601f870116820101915050611fda606083018480518252602090810151910152565b634e487b7160e01b600052603160045260246000fdfe6d439300980e333f0256d64be2c9f67e86f4493ce25f82498d6db7f4be3d9e6fa26469706673582212207618a3a0388d1529251f39c1ac32bb8b809302c9c89c2429b9ddf075b9282cdb64736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072e28c7f34100afefc399fcc0ae041b8fe5841ae00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _registry (address): 0x0000000000000000000000000000000000000000
Arg [1] : _actionIdOffset (uint256): 0
Arg [2] : _owner (address): 0x72E28c7F34100AfefC399fcc0AE041B8fe5841AE
Arg [3] : _managers (address[]):
Arg [4] : _addOwnerToManagers (bool): True
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [2] : 00000000000000000000000072e28c7f34100afefc399fcc0ae041b8fe5841ae
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.