Source Code
Overview
MNT Balance
MNT Value
$0.00
Cross-Chain Transactions
Loading...
Loading
Contract Name:
GhoCcipSteward
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 200 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
import {IUpgradeableLockReleaseTokenPool, RateLimiter} from './dependencies/Ccip.sol';
import {IGhoCcipSteward} from './interfaces/IGhoCcipSteward.sol';
import {RiskCouncilControlled} from './RiskCouncilControlled.sol';
/**
* @title GhoCcipSteward
* @author Aave Labs
* @notice Helper contract for managing parameters of the CCIP token pools
* @dev Only the Risk Council is able to action contract's functions, based on specific conditions that have been agreed upon with the community.
* @dev Requires roles RateLimitAdmin and BridgeLimitAdmin (if on Ethereum) on GhoTokenPool
*/
contract GhoCcipSteward is RiskCouncilControlled, IGhoCcipSteward {
/// @inheritdoc IGhoCcipSteward
uint256 public constant MINIMUM_DELAY = 1 days;
/// @inheritdoc IGhoCcipSteward
address public immutable GHO_TOKEN;
/// @inheritdoc IGhoCcipSteward
address public immutable GHO_TOKEN_POOL;
/// @inheritdoc IGhoCcipSteward
bool public immutable BRIDGE_LIMIT_ENABLED;
CcipDebounce internal _ccipTimelocks;
/**
* @dev Only methods that are not timelocked can be called if marked by this modifier.
*/
modifier notTimelocked(uint40 timelock) {
require(block.timestamp - timelock > MINIMUM_DELAY, 'DEBOUNCE_NOT_RESPECTED');
_;
}
/**
* @dev Constructor
* @param ghoToken The address of the GhoToken
* @param ghoTokenPool The address of the Gho CCIP Token Pool
* @param riskCouncil The address of the risk council
* @param bridgeLimitEnabled Whether the bridge limit feature is supported in the GhoTokenPool
*/
constructor(
address ghoToken,
address ghoTokenPool,
address riskCouncil,
bool bridgeLimitEnabled
) RiskCouncilControlled(riskCouncil) {
require(ghoToken != address(0), 'INVALID_GHO_TOKEN');
require(ghoTokenPool != address(0), 'INVALID_GHO_TOKEN_POOL');
GHO_TOKEN = ghoToken;
GHO_TOKEN_POOL = ghoTokenPool;
BRIDGE_LIMIT_ENABLED = bridgeLimitEnabled;
}
/// @inheritdoc IGhoCcipSteward
function updateBridgeLimit(
uint256 newBridgeLimit
) external onlyRiskCouncil notTimelocked(_ccipTimelocks.bridgeLimitLastUpdate) {
require(BRIDGE_LIMIT_ENABLED, 'BRIDGE_LIMIT_DISABLED');
uint256 currentBridgeLimit = IUpgradeableLockReleaseTokenPool(GHO_TOKEN_POOL).getBridgeLimit();
require(newBridgeLimit != currentBridgeLimit, 'NO_CHANGE_IN_BRIDGE_LIMIT');
require(
_isDifferenceLowerThanMax(currentBridgeLimit, newBridgeLimit, currentBridgeLimit),
'INVALID_BRIDGE_LIMIT_UPDATE'
);
_ccipTimelocks.bridgeLimitLastUpdate = uint40(block.timestamp);
IUpgradeableLockReleaseTokenPool(GHO_TOKEN_POOL).setBridgeLimit(newBridgeLimit);
}
/// @inheritdoc IGhoCcipSteward
function updateRateLimit(
uint64 remoteChainSelector,
bool outboundEnabled,
uint128 outboundCapacity,
uint128 outboundRate,
bool inboundEnabled,
uint128 inboundCapacity,
uint128 inboundRate
) external onlyRiskCouncil notTimelocked(_ccipTimelocks.rateLimitLastUpdate) {
RateLimiter.TokenBucket memory outboundConfig = IUpgradeableLockReleaseTokenPool(GHO_TOKEN_POOL)
.getCurrentOutboundRateLimiterState(remoteChainSelector);
RateLimiter.TokenBucket memory inboundConfig = IUpgradeableLockReleaseTokenPool(GHO_TOKEN_POOL)
.getCurrentInboundRateLimiterState(remoteChainSelector);
require(
outboundEnabled != outboundConfig.isEnabled ||
outboundCapacity != outboundConfig.capacity ||
outboundRate != outboundConfig.rate ||
inboundEnabled != inboundConfig.isEnabled ||
inboundCapacity != inboundConfig.capacity ||
inboundRate != inboundConfig.rate,
'NO_CHANGE_IN_RATE_LIMIT'
);
require(
_isDifferenceLowerThanMax(outboundConfig.capacity, outboundCapacity, outboundConfig.capacity),
'INVALID_RATE_LIMIT_UPDATE'
);
require(
_isDifferenceLowerThanMax(outboundConfig.rate, outboundRate, outboundConfig.rate),
'INVALID_RATE_LIMIT_UPDATE'
);
require(
_isDifferenceLowerThanMax(inboundConfig.capacity, inboundCapacity, inboundConfig.capacity),
'INVALID_RATE_LIMIT_UPDATE'
);
require(
_isDifferenceLowerThanMax(inboundConfig.rate, inboundRate, inboundConfig.rate),
'INVALID_RATE_LIMIT_UPDATE'
);
_ccipTimelocks.rateLimitLastUpdate = uint40(block.timestamp);
IUpgradeableLockReleaseTokenPool(GHO_TOKEN_POOL).setChainRateLimiterConfig(
remoteChainSelector,
RateLimiter.Config({
isEnabled: outboundEnabled,
capacity: outboundCapacity,
rate: outboundRate
}),
RateLimiter.Config({isEnabled: inboundEnabled, capacity: inboundCapacity, rate: inboundRate})
);
}
/// @inheritdoc IGhoCcipSteward
function getCcipTimelocks() external view override returns (CcipDebounce memory) {
return _ccipTimelocks;
}
/// @inheritdoc IGhoCcipSteward
function RISK_COUNCIL() external view override returns (address) {
return _riskCouncil;
}
/**
* @dev Ensures that the change difference is lower than max.
* @param from current value
* @param to new value
* @param max maximum difference between from and to
* @return bool true if difference between values lower than max, false otherwise
*/
function _isDifferenceLowerThanMax(
uint256 from,
uint256 to,
uint256 max
) internal pure returns (bool) {
return from < to ? to - from <= max : from - to <= max;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// End consumer library.
library Client {
/// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.
struct EVMTokenAmount {
address token; // token address on the local chain.
uint256 amount; // Amount of tokens.
}
struct Any2EVMMessage {
bytes32 messageId; // MessageId corresponding to ccipSend on source.
uint64 sourceChainSelector; // Source chain selector.
bytes sender; // abi.decode(sender) if coming from an EVM chain.
bytes data; // payload sent in original message.
EVMTokenAmount[] destTokenAmounts; // Tokens and their amounts in their destination chain representation.
}
// If extraArgs is empty bytes, the default is 200k gas limit.
struct EVM2AnyMessage {
bytes receiver; // abi.encode(receiver address) for dest EVM chains
bytes data; // Data payload
EVMTokenAmount[] tokenAmounts; // Token transfers
address feeToken; // Address of feeToken. address(0) means you will send msg.value.
bytes extraArgs; // Populate this with _argsToBytes(EVMExtraArgsV1)
}
// bytes4(keccak256("CCIP EVMExtraArgsV1"));
bytes4 public constant EVM_EXTRA_ARGS_V1_TAG = 0x97a657c9;
struct EVMExtraArgsV1 {
uint256 gasLimit;
}
function _argsToBytes(EVMExtraArgsV1 memory extraArgs) internal pure returns (bytes memory bts) {
return abi.encodeWithSelector(EVM_EXTRA_ARGS_V1_TAG, extraArgs);
}
}
/// @notice Implements Token Bucket rate limiting.
/// @dev Reduced library from https://github.com/aave/ccip/blob/ccip-gho/contracts/src/v0.8/ccip/libraries/RateLimiter.sol
/// @dev uint128 is safe for rate limiter state.
/// For USD value rate limiting, it can adequately store USD value in 18 decimals.
/// For ERC20 token amount rate limiting, all tokens that will be listed will have at most
/// a supply of uint128.max tokens, and it will therefore not overflow the bucket.
/// In exceptional scenarios where tokens consumed may be larger than uint128,
/// e.g. compromised issuer, an enabled RateLimiter will check and revert.
library RateLimiter {
error InvalidRatelimitRate(Config rateLimiterConfig);
error DisabledNonZeroRateLimit(Config config);
error RateLimitMustBeDisabled();
event ConfigChanged(Config config);
struct TokenBucket {
uint128 tokens; // ──────╮ Current number of tokens that are in the bucket.
uint32 lastUpdated; // │ Timestamp in seconds of the last token refill, good for 100+ years.
bool isEnabled; // ──────╯ Indication whether the rate limiting is enabled or not
uint128 capacity; // ────╮ Maximum number of tokens that can be in the bucket.
uint128 rate; // ────────╯ Number of tokens per second that the bucket is refilled.
}
struct Config {
bool isEnabled; // Indication whether the rate limiting should be enabled
uint128 capacity; // ────╮ Specifies the capacity of the rate limiter
uint128 rate; // ───────╯ Specifies the rate of the rate limiter
}
/// @notice Gets the token bucket with its values for the block it was requested at.
/// @return The token bucket.
function _currentTokenBucketState(
TokenBucket memory bucket
) internal view returns (TokenBucket memory) {
// We update the bucket to reflect the status at the exact time of the
// call. This means we might need to refill a part of the bucket based
// on the time that has passed since the last update.
bucket.tokens = uint128(
_calculateRefill(
bucket.capacity,
bucket.tokens,
block.timestamp - bucket.lastUpdated,
bucket.rate
)
);
bucket.lastUpdated = uint32(block.timestamp);
return bucket;
}
/// @notice Sets the rate limited config.
/// @param s_bucket The token bucket
/// @param config The new config
function _setTokenBucketConfig(TokenBucket storage s_bucket, Config memory config) internal {
// First update the bucket to make sure the proper rate is used for all the time
// up until the config change.
uint256 timeDiff = block.timestamp - s_bucket.lastUpdated;
if (timeDiff != 0) {
s_bucket.tokens = uint128(
_calculateRefill(s_bucket.capacity, s_bucket.tokens, timeDiff, s_bucket.rate)
);
s_bucket.lastUpdated = uint32(block.timestamp);
}
s_bucket.tokens = uint128(_min(config.capacity, s_bucket.tokens));
s_bucket.isEnabled = config.isEnabled;
s_bucket.capacity = config.capacity;
s_bucket.rate = config.rate;
emit ConfigChanged(config);
}
/// @notice Validates the token bucket config
function _validateTokenBucketConfig(Config memory config, bool mustBeDisabled) internal pure {
if (config.isEnabled) {
if (config.rate >= config.capacity || config.rate == 0) {
revert InvalidRatelimitRate(config);
}
if (mustBeDisabled) {
revert RateLimitMustBeDisabled();
}
} else {
if (config.rate != 0 || config.capacity != 0) {
revert DisabledNonZeroRateLimit(config);
}
}
}
/// @notice Calculate refilled tokens
/// @param capacity bucket capacity
/// @param tokens current bucket tokens
/// @param timeDiff block time difference since last refill
/// @param rate bucket refill rate
/// @return the value of tokens after refill
function _calculateRefill(
uint256 capacity,
uint256 tokens,
uint256 timeDiff,
uint256 rate
) private pure returns (uint256) {
return _min(capacity, tokens + timeDiff * rate);
}
/// @notice Return the smallest of two integers
/// @param a first int
/// @param b second int
/// @return smallest
function _min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
}
/// @dev Reduced interface of CCIP Router contract with needed functions only
/// @dev Adapted from https://github.com/aave/ccip/blob/ccip-gho/contracts/src/v0.8/ccip/interfaces/IRouter.sol
interface IRouter {
error OnlyOffRamp();
/// @notice Route the message to its intended receiver contract.
/// @param message Client.Any2EVMMessage struct.
/// @param gasForCallExactCheck of params for exec
/// @param gasLimit set of params for exec
/// @param receiver set of params for exec
/// @dev if the receiver is a contracts that signals support for CCIP execution through EIP-165.
/// the contract is called. If not, only tokens are transferred.
/// @return success A boolean value indicating whether the ccip message was received without errors.
/// @return retBytes A bytes array containing return data form CCIP receiver.
/// @return gasUsed the gas used by the external customer call. Does not include any overhead.
function routeMessage(
Client.Any2EVMMessage calldata message,
uint16 gasForCallExactCheck,
uint256 gasLimit,
address receiver
) external returns (bool success, bytes memory retBytes, uint256 gasUsed);
/// @notice Returns the configured onramp for a specific destination chain.
/// @param destChainSelector The destination chain Id to get the onRamp for.
/// @return onRampAddress The address of the onRamp.
function getOnRamp(uint64 destChainSelector) external view returns (address onRampAddress);
/// @notice Return true if the given offRamp is a configured offRamp for the given source chain.
/// @param sourceChainSelector The source chain selector to check.
/// @param offRamp The address of the offRamp to check.
function isOffRamp(
uint64 sourceChainSelector,
address offRamp
) external view returns (bool isOffRamp);
}
/// @dev Reduced interface of CCIP UpgradeableLockReleaseTokenPool contract with needed functions only
/// @dev Adapted from https://github.com/aave/ccip/blob/ccip-gho/contracts/src/v0.8/ccip/pools/GHO/UpgradeableLockReleaseTokenPool.sol
interface IUpgradeableLockReleaseTokenPool {
function setBridgeLimit(uint256 newBridgeLimit) external;
function setChainRateLimiterConfig(
uint64 remoteChainSelector,
RateLimiter.Config memory outboundConfig,
RateLimiter.Config memory inboundConfig
) external;
function setRateLimitAdmin(address rateLimitAdmin) external;
function setBridgeLimitAdmin(address bridgeLimitAdmin) external;
function getRateLimitAdmin() external view returns (address);
function getBridgeLimitAdmin() external view returns (address);
function getBridgeLimit() external view returns (uint256);
function getCurrentOutboundRateLimiterState(
uint64 remoteChainSelector
) external view returns (RateLimiter.TokenBucket memory);
function getCurrentInboundRateLimiterState(
uint64 remoteChainSelector
) external view returns (RateLimiter.TokenBucket memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
/**
* @title IGhoCcipSteward
* @author Aave Labs
* @notice Defines the basic interface of the GhoCcipSteward
*/
interface IGhoCcipSteward {
/**
* @notice Struct storing the last update by the steward of the bridge and rate limit param.
*/
struct CcipDebounce {
uint40 bridgeLimitLastUpdate;
uint40 rateLimitLastUpdate;
}
/**
* @notice Updates the CCIP bridge limit
* @dev Only callable by Risk Council
* @param newBridgeLimit The new desired bridge limit
*/
function updateBridgeLimit(uint256 newBridgeLimit) external;
/**
* @notice Updates the CCIP rate limit config
* @dev Only callable by Risk Council
* @dev Rate limit update must be consistent with other pools' rate limit
* @param remoteChainSelector The remote chain selector for which the rate limits apply.
* @param outboundEnabled True if the outbound rate limiter is enabled.
* @param outboundCapacity The outbound rate limiter capacity.
* @param outboundRate The outbound rate limiter rate.
* @param inboundEnabled True if the inbound rate limiter is enabled.
* @param inboundCapacity The inbound rate limiter capacity.
* @param inboundRate The inbound rate limiter rate.
*/
function updateRateLimit(
uint64 remoteChainSelector,
bool outboundEnabled,
uint128 outboundCapacity,
uint128 outboundRate,
bool inboundEnabled,
uint128 inboundCapacity,
uint128 inboundRate
) external;
/**
* @notice Returns timestamp of the last update of Ccip parameters.
* @return The CcipDebounce struct describing the last update of Ccip parameters.
*/
function getCcipTimelocks() external view returns (CcipDebounce memory);
/**
* @notice Returns the minimum delay that must be respected between parameters update.
* @return The minimum delay between parameter updates (in seconds)
*/
function MINIMUM_DELAY() external view returns (uint256);
/**
* @notice Returns the address of the Gho Token
* @return The address of the GhoToken
*/
function GHO_TOKEN() external view returns (address);
/**
* @notice Returns the address of the Gho CCIP Token Pool
* @return The address of the Gho CCIP Token Pool
*/
function GHO_TOKEN_POOL() external view returns (address);
/**
* @notice Returns whether the bridge limit feature is supported in the GhoTokenPool
* @return True if bridge limit is enabled in the CCIP GhoTokenPool, false otherwise
*/
function BRIDGE_LIMIT_ENABLED() external view returns (bool);
/**
* @notice Returns the address of the risk council
* @return The address of the RiskCouncil
*/
function RISK_COUNCIL() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
/**
* @title RiskCouncilControlled
* @author Aave Labs
* @notice Helper contract for controlling access to Steward and other functions restricted to Risk Council
*/
abstract contract RiskCouncilControlled {
address internal immutable _riskCouncil;
/**
* @dev Constructor
* @param riskCouncil The address of the risk council
*/
constructor(address riskCouncil) {
require(riskCouncil != address(0), 'INVALID_RISK_COUNCIL');
_riskCouncil = riskCouncil;
}
/**
* @dev Only Risk Council can call functions marked by this modifier.
*/
modifier onlyRiskCouncil() {
require(_riskCouncil == msg.sender, 'INVALID_CALLER');
_;
}
}{
"remappings": [
"@aave/core-v3/=lib/aave-v3-core/",
"@aave/periphery-v3/=lib/aave-v3-periphery/",
"@aave/=lib/aave-token/",
"@openzeppelin/=lib/openzeppelin-contracts/",
"aave-stk-v1-5/=lib/aave-stk-v1-5/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"eth-gas-reporter/=node_modules/eth-gas-reporter/",
"forge-std/=lib/forge-std/src/",
"hardhat-deploy/=node_modules/hardhat-deploy/",
"hardhat/=node_modules/hardhat/",
"aave-address-book/=lib/aave-address-book/src/",
"aave-helpers/=lib/aave-stk-v1-5/lib/aave-helpers/",
"aave-v3-core/=lib/aave-address-book/lib/aave-v3-core/",
"aave-v3-periphery/=lib/aave-address-book/lib/aave-v3-periphery/",
"erc4626-tests/=lib/aave-stk-v1-5/lib/openzeppelin-contracts/lib/erc4626-tests/",
"openzeppelin-contracts/=lib/aave-stk-v1-5/lib/openzeppelin-contracts/",
"solidity-utils/=lib/solidity-utils/src/",
"aave-token/=lib/aave-token/contracts/",
"safety-module/=lib/safety-module/contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs"
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "london",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"ghoToken","type":"address"},{"internalType":"address","name":"ghoTokenPool","type":"address"},{"internalType":"address","name":"riskCouncil","type":"address"},{"internalType":"bool","name":"bridgeLimitEnabled","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BRIDGE_LIMIT_ENABLED","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GHO_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GHO_TOKEN_POOL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINIMUM_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RISK_COUNCIL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCcipTimelocks","outputs":[{"components":[{"internalType":"uint40","name":"bridgeLimitLastUpdate","type":"uint40"},{"internalType":"uint40","name":"rateLimitLastUpdate","type":"uint40"}],"internalType":"struct IGhoCcipSteward.CcipDebounce","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newBridgeLimit","type":"uint256"}],"name":"updateBridgeLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"remoteChainSelector","type":"uint64"},{"internalType":"bool","name":"outboundEnabled","type":"bool"},{"internalType":"uint128","name":"outboundCapacity","type":"uint128"},{"internalType":"uint128","name":"outboundRate","type":"uint128"},{"internalType":"bool","name":"inboundEnabled","type":"bool"},{"internalType":"uint128","name":"inboundCapacity","type":"uint128"},{"internalType":"uint128","name":"inboundRate","type":"uint128"}],"name":"updateRateLimit","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
61010060405234801561001157600080fd5b50604051610ecc380380610ecc8339810160408190526100309161016e565b816001600160a01b03811661008c5760405162461bcd60e51b815260206004820152601460248201527f494e56414c49445f5249534b5f434f554e43494c00000000000000000000000060448201526064015b60405180910390fd5b6001600160a01b0390811660805284166100dc5760405162461bcd60e51b815260206004820152601160248201527024a72b20a624a22fa3a427afaa27a5a2a760791b6044820152606401610083565b6001600160a01b0383166101325760405162461bcd60e51b815260206004820152601660248201527f494e56414c49445f47484f5f544f4b454e5f504f4f4c000000000000000000006044820152606401610083565b6001600160a01b0393841660a0529190921660c052151560e052506101c9565b80516001600160a01b038116811461016957600080fd5b919050565b6000806000806080858703121561018457600080fd5b61018d85610152565b935061019b60208601610152565b92506101a960408601610152565b9150606085015180151581146101be57600080fd5b939692955090935050565b60805160a05160c05160e051610c93610239600039600081816101b301526102b30152600081816101250152818161031a01528181610470015281816105cb0152818161066b015261092101526000610164015260008181608f015281816101e701526104db0152610c936000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063b1c660f71161005b578063b1c660f71461015f578063c3631a1a14610186578063c40b59591461019b578063d42e41ab146101ae57600080fd5b806311aa16701461008d5780636128807d146100cc578063ab2c0b2114610120578063b1b43ae514610147575b600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020015b60405180910390f35b6040805180820182526000808252602091820181905282518084018452905464ffffffffff8082168084526501000000000090920481169284019283528451918252915190911691810191909152016100c3565b6100af7f000000000000000000000000000000000000000000000000000000000000000081565b6101516201518081565b6040519081526020016100c3565b6100af7f000000000000000000000000000000000000000000000000000000000000000081565b6101996101943660046109ce565b6101e5565b005b6101996101a9366004610a0d565b6104d9565b6101d57f000000000000000000000000000000000000000000000000000000000000000081565b60405190151581526020016100c3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633146102535760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa1a0a62622a960911b60448201526064015b60405180910390fd5b60005464ffffffffff166201518061026b8242610ab0565b116102b15760405162461bcd60e51b815260206004820152601660248201527511115093d55390d157d393d517d49154d41150d5115160521b604482015260640161024a565b7f00000000000000000000000000000000000000000000000000000000000000006103165760405162461bcd60e51b81526020600482015260156024820152741094925111d157d31253525517d11254d050931151605a1b604482015260640161024a565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e7887f196040518163ffffffff1660e01b8152600401602060405180830381865afa158015610376573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039a9190610ad5565b9050808314156103ec5760405162461bcd60e51b815260206004820152601960248201527f4e4f5f4348414e47455f494e5f4252494447455f4c494d495400000000000000604482015260640161024a565b6103f781848361099d565b6104435760405162461bcd60e51b815260206004820152601b60248201527f494e56414c49445f4252494447455f4c494d49545f5550444154450000000000604482015260640161024a565b6000805464ffffffffff19164264ffffffffff16179055604051633c95a59160e11b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063792b4b2290602401600060405180830381600087803b1580156104bc57600080fd5b505af11580156104d0573d6000803e3d6000fd5b50505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633146105425760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa1a0a62622a960911b604482015260640161024a565b60005465010000000000900464ffffffffff16620151806105638242610ab0565b116105a95760405162461bcd60e51b815260206004820152601660248201527511115093d55390d157d393d517d49154d41150d5115160521b604482015260640161024a565b6040516331d7baa760e21b815267ffffffffffffffff891660048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c75eea9c9060240160a060405180830381865afa15801561061a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063e9190610b09565b60405163af58d59f60e01b815267ffffffffffffffff8b1660048201529091506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063af58d59f9060240160a060405180830381865afa1580156106b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d69190610b09565b905081604001511515891515141580610705575081606001516001600160801b0316886001600160801b031614155b80610726575081608001516001600160801b0316876001600160801b031614155b8061073957508060400151151586151514155b8061075a575080606001516001600160801b0316856001600160801b031614155b8061077b575080608001516001600160801b0316846001600160801b031614155b6107c75760405162461bcd60e51b815260206004820152601760248201527f4e4f5f4348414e47455f494e5f524154455f4c494d4954000000000000000000604482015260640161024a565b60608201516107e4906001600160801b03908116908a168161099d565b6108005760405162461bcd60e51b815260040161024a90610bb2565b608082015161081d906001600160801b039081169089168161099d565b6108395760405162461bcd60e51b815260040161024a90610bb2565b6060810151610856906001600160801b039081169087168161099d565b6108725760405162461bcd60e51b815260040161024a90610bb2565b608081015161088f906001600160801b039081169086168161099d565b6108ab5760405162461bcd60e51b815260040161024a90610bb2565b6000805469ffffffffff00000000001916650100000000004264ffffffffff160217905560408051606080820183528b151582526001600160801b038b81166020808501919091528b821684860152845192830185528a1515835289821690830152871681840152915163cf7401f360e01b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169263cf7401f39261095f928f9290600401610be9565b600060405180830381600087803b15801561097957600080fd5b505af115801561098d573d6000803e3d6000fd5b5050505050505050505050505050565b60008284106109b857816109b18486610ab0565b11156109c6565b816109c38585610ab0565b11155b949350505050565b6000602082840312156109e057600080fd5b5035919050565b80151581146109f557600080fd5b50565b6001600160801b03811681146109f557600080fd5b600080600080600080600060e0888a031215610a2857600080fd5b873567ffffffffffffffff81168114610a4057600080fd5b96506020880135610a50816109e7565b95506040880135610a60816109f8565b94506060880135610a70816109f8565b93506080880135610a80816109e7565b925060a0880135610a90816109f8565b915060c0880135610aa0816109f8565b8091505092959891949750929550565b600082821015610ad057634e487b7160e01b600052601160045260246000fd5b500390565b600060208284031215610ae757600080fd5b5051919050565b8051610af9816109f8565b919050565b8051610af9816109e7565b600060a08284031215610b1b57600080fd5b60405160a0810181811067ffffffffffffffff82111715610b4c57634e487b7160e01b600052604160045260246000fd5b6040528251610b5a816109f8565b8152602083015163ffffffff81168114610b7357600080fd5b6020820152610b8460408401610afe565b6040820152610b9560608401610aee565b6060820152610ba660808401610aee565b60808201529392505050565b60208082526019908201527f494e56414c49445f524154455f4c494d49545f55504441544500000000000000604082015260600190565b67ffffffffffffffff8416815260e08101610c2c60208301858051151582526020808201516001600160801b039081169184019190915260409182015116910152565b82511515608083015260208301516001600160801b0390811660a084015260408401511660c083015294935050505056fea264697066735822122088ec034445623aeb0466b46098677943600c54f9ffbe1c87397d7b41c294cc1164736f6c634300080a0033000000000000000000000000fc421ad3c883bf9e7c4f42de845c4e4405799e73000000000000000000000000de6539018b095353a40753dc54c91c68c9487d4e0000000000000000000000008513e6f37dbc52de87b166980fa3f50639694b600000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063b1c660f71161005b578063b1c660f71461015f578063c3631a1a14610186578063c40b59591461019b578063d42e41ab146101ae57600080fd5b806311aa16701461008d5780636128807d146100cc578063ab2c0b2114610120578063b1b43ae514610147575b600080fd5b7f0000000000000000000000008513e6f37dbc52de87b166980fa3f50639694b605b6040516001600160a01b0390911681526020015b60405180910390f35b6040805180820182526000808252602091820181905282518084018452905464ffffffffff8082168084526501000000000090920481169284019283528451918252915190911691810191909152016100c3565b6100af7f000000000000000000000000de6539018b095353a40753dc54c91c68c9487d4e81565b6101516201518081565b6040519081526020016100c3565b6100af7f000000000000000000000000fc421ad3c883bf9e7c4f42de845c4e4405799e7381565b6101996101943660046109ce565b6101e5565b005b6101996101a9366004610a0d565b6104d9565b6101d57f000000000000000000000000000000000000000000000000000000000000000081565b60405190151581526020016100c3565b7f0000000000000000000000008513e6f37dbc52de87b166980fa3f50639694b606001600160a01b031633146102535760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa1a0a62622a960911b60448201526064015b60405180910390fd5b60005464ffffffffff166201518061026b8242610ab0565b116102b15760405162461bcd60e51b815260206004820152601660248201527511115093d55390d157d393d517d49154d41150d5115160521b604482015260640161024a565b7f00000000000000000000000000000000000000000000000000000000000000006103165760405162461bcd60e51b81526020600482015260156024820152741094925111d157d31253525517d11254d050931151605a1b604482015260640161024a565b60007f000000000000000000000000de6539018b095353a40753dc54c91c68c9487d4e6001600160a01b031663e7887f196040518163ffffffff1660e01b8152600401602060405180830381865afa158015610376573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039a9190610ad5565b9050808314156103ec5760405162461bcd60e51b815260206004820152601960248201527f4e4f5f4348414e47455f494e5f4252494447455f4c494d495400000000000000604482015260640161024a565b6103f781848361099d565b6104435760405162461bcd60e51b815260206004820152601b60248201527f494e56414c49445f4252494447455f4c494d49545f5550444154450000000000604482015260640161024a565b6000805464ffffffffff19164264ffffffffff16179055604051633c95a59160e11b8152600481018490527f000000000000000000000000de6539018b095353a40753dc54c91c68c9487d4e6001600160a01b03169063792b4b2290602401600060405180830381600087803b1580156104bc57600080fd5b505af11580156104d0573d6000803e3d6000fd5b50505050505050565b7f0000000000000000000000008513e6f37dbc52de87b166980fa3f50639694b606001600160a01b031633146105425760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa1a0a62622a960911b604482015260640161024a565b60005465010000000000900464ffffffffff16620151806105638242610ab0565b116105a95760405162461bcd60e51b815260206004820152601660248201527511115093d55390d157d393d517d49154d41150d5115160521b604482015260640161024a565b6040516331d7baa760e21b815267ffffffffffffffff891660048201526000907f000000000000000000000000de6539018b095353a40753dc54c91c68c9487d4e6001600160a01b03169063c75eea9c9060240160a060405180830381865afa15801561061a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063e9190610b09565b60405163af58d59f60e01b815267ffffffffffffffff8b1660048201529091506000906001600160a01b037f000000000000000000000000de6539018b095353a40753dc54c91c68c9487d4e169063af58d59f9060240160a060405180830381865afa1580156106b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d69190610b09565b905081604001511515891515141580610705575081606001516001600160801b0316886001600160801b031614155b80610726575081608001516001600160801b0316876001600160801b031614155b8061073957508060400151151586151514155b8061075a575080606001516001600160801b0316856001600160801b031614155b8061077b575080608001516001600160801b0316846001600160801b031614155b6107c75760405162461bcd60e51b815260206004820152601760248201527f4e4f5f4348414e47455f494e5f524154455f4c494d4954000000000000000000604482015260640161024a565b60608201516107e4906001600160801b03908116908a168161099d565b6108005760405162461bcd60e51b815260040161024a90610bb2565b608082015161081d906001600160801b039081169089168161099d565b6108395760405162461bcd60e51b815260040161024a90610bb2565b6060810151610856906001600160801b039081169087168161099d565b6108725760405162461bcd60e51b815260040161024a90610bb2565b608081015161088f906001600160801b039081169086168161099d565b6108ab5760405162461bcd60e51b815260040161024a90610bb2565b6000805469ffffffffff00000000001916650100000000004264ffffffffff160217905560408051606080820183528b151582526001600160801b038b81166020808501919091528b821684860152845192830185528a1515835289821690830152871681840152915163cf7401f360e01b81527f000000000000000000000000de6539018b095353a40753dc54c91c68c9487d4e6001600160a01b03169263cf7401f39261095f928f9290600401610be9565b600060405180830381600087803b15801561097957600080fd5b505af115801561098d573d6000803e3d6000fd5b5050505050505050505050505050565b60008284106109b857816109b18486610ab0565b11156109c6565b816109c38585610ab0565b11155b949350505050565b6000602082840312156109e057600080fd5b5035919050565b80151581146109f557600080fd5b50565b6001600160801b03811681146109f557600080fd5b600080600080600080600060e0888a031215610a2857600080fd5b873567ffffffffffffffff81168114610a4057600080fd5b96506020880135610a50816109e7565b95506040880135610a60816109f8565b94506060880135610a70816109f8565b93506080880135610a80816109e7565b925060a0880135610a90816109f8565b915060c0880135610aa0816109f8565b8091505092959891949750929550565b600082821015610ad057634e487b7160e01b600052601160045260246000fd5b500390565b600060208284031215610ae757600080fd5b5051919050565b8051610af9816109f8565b919050565b8051610af9816109e7565b600060a08284031215610b1b57600080fd5b60405160a0810181811067ffffffffffffffff82111715610b4c57634e487b7160e01b600052604160045260246000fd5b6040528251610b5a816109f8565b8152602083015163ffffffff81168114610b7357600080fd5b6020820152610b8460408401610afe565b6040820152610b9560608401610aee565b6060820152610ba660808401610aee565b60808201529392505050565b60208082526019908201527f494e56414c49445f524154455f4c494d49545f55504441544500000000000000604082015260600190565b67ffffffffffffffff8416815260e08101610c2c60208301858051151582526020808201516001600160801b039081169184019190915260409182015116910152565b82511515608083015260208301516001600160801b0390811660a084015260408401511660c083015294935050505056fea264697066735822122088ec034445623aeb0466b46098677943600c54f9ffbe1c87397d7b41c294cc1164736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000fc421ad3c883bf9e7c4f42de845c4e4405799e73000000000000000000000000de6539018b095353a40753dc54c91c68c9487d4e0000000000000000000000008513e6f37dbc52de87b166980fa3f50639694b600000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : ghoToken (address): 0xfc421aD3C883Bf9E7C4f42dE845C4e4405799e73
Arg [1] : ghoTokenPool (address): 0xDe6539018B095353A40753Dc54C91C68c9487D4E
Arg [2] : riskCouncil (address): 0x8513e6F37dBc52De87b166980Fa3F50639694B60
Arg [3] : bridgeLimitEnabled (bool): False
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000fc421ad3c883bf9e7c4f42de845c4e4405799e73
Arg [1] : 000000000000000000000000de6539018b095353a40753dc54c91c68c9487d4e
Arg [2] : 0000000000000000000000008513e6f37dbc52de87b166980fa3f50639694b60
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in MNT
Multichain Portfolio | 32 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.