Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
StrategyKeeperSablierValidator
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 100 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.24;
import {IValidator} from "lib/yieldnest-flex-strategy/lib/yieldnest-vault/src/interface/IValidator.sol";
import {ISablierLockupLinear} from "src/interfaces/sablier/ISablierLockupLinear.sol";
import {ISablierBatchLockup} from "src/interfaces/sablier/ISablierBatchLockup.sol";
import {IERC20} from "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
/// @title StrategyKeeperSablierValidator
/// @notice Validates Sablier stream creation parameters for the strategy keeper
/// @dev Ensures that streams created via the processor meet security requirements:
/// - sender must be the configured safe
/// - recipient must be in the allowed recipients list
/// - token must be the configured token
/// - stream must be cancelable
/// - stream must be transferable
/// Supports both single stream (ISablierLockupLinear) and batch stream (ISablierBatchLockup) creation.
contract StrategyKeeperSablierValidator is IValidator {
string public constant VERSION = "0.2.0";
/*//////////////////////////////////////////////////////////////
ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when the function selector doesn't match a supported function
error InvalidFunctionSelector(bytes4 selector);
/// @notice Thrown when the sender is not the configured safe
error InvalidSender(address sender, address expectedSafe);
/// @notice Thrown when the recipient is not in the allowed list
error InvalidRecipient(address recipient);
/// @notice Thrown when the token is not the configured token
error InvalidToken(address token, address expectedToken);
/// @notice Thrown when the stream is not cancelable
error StreamMustBeCancelable();
/// @notice Thrown when the stream is not transferable
error StreamMustBeTransferable();
/// @notice Thrown when an address is zero
error ZeroAddress();
/// @notice Thrown when the allowed recipients array is empty
error EmptyAllowedRecipients();
/// @notice Thrown when the lockup address doesn't match the configured lockup
error InvalidLockupAddress(address lockup, address expectedLockup);
/// @notice Thrown when the batch array is empty
error EmptyBatch();
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
/// @notice Emitted when the validator is configured
event ValidatorConfigured(address indexed safe, address indexed token, address[] allowedRecipients);
/*//////////////////////////////////////////////////////////////
STORAGE
//////////////////////////////////////////////////////////////*/
/// @notice The safe address that must be the sender of the stream
address public immutable safe;
/// @notice The Sablier LockupLinear contract address (validated in batch calls)
address public immutable lockup;
/// @notice The token that must be used for the stream
address public immutable token;
/// @notice Mapping of allowed recipients
mapping(address => bool) public isAllowedRecipient;
/// @notice Array of allowed recipients (for enumeration)
address[] public allowedRecipients;
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
/// @notice Creates a new StrategyKeeperSablierValidator
/// @param _safe The safe address that must be the sender of streams
/// @param _lockup The Sablier LockupLinear contract address
/// @param _token The token address that must be used for streams
/// @param _allowedRecipients Array of addresses that can receive streams
constructor(address _safe, address _lockup, address _token, address[] memory _allowedRecipients) {
if (_safe == address(0)) revert ZeroAddress();
if (_lockup == address(0)) revert ZeroAddress();
if (_token == address(0)) revert ZeroAddress();
if (_allowedRecipients.length == 0) revert EmptyAllowedRecipients();
safe = _safe;
lockup = _lockup;
token = _token;
for (uint256 i = 0; i < _allowedRecipients.length; i++) {
if (_allowedRecipients[i] == address(0)) revert ZeroAddress();
isAllowedRecipient[_allowedRecipients[i]] = true;
allowedRecipients.push(_allowedRecipients[i]);
}
emit ValidatorConfigured(_safe, _token, _allowedRecipients);
}
/*//////////////////////////////////////////////////////////////
EXTERNAL FUNCTIONS
//////////////////////////////////////////////////////////////*/
/// @notice Validates a Sablier stream creation call (single or batch)
/// @param target The Sablier contract address (not validated here, should be validated by the rule)
/// @param value The ETH value (should be 0 for this call)
/// @param data The calldata containing the function selector and parameters
/// @dev Reverts if any validation check fails
function validate(address target, uint256 value, bytes calldata data) external view override {
// Suppress unused variable warning
target;
value;
// Check minimum data length (4 bytes selector + params)
if (data.length < 4) revert InvalidFunctionSelector(bytes4(0));
// Extract and verify function selector
bytes4 selector = bytes4(data[:4]);
if (selector == ISablierLockupLinear.createWithTimestampsLL.selector) {
_validateSingle(data[4:]);
} else if (selector == ISablierBatchLockup.createWithTimestampsLL.selector) {
_validateBatch(data[4:]);
} else {
revert InvalidFunctionSelector(selector);
}
}
/*//////////////////////////////////////////////////////////////
INTERNAL FUNCTIONS
//////////////////////////////////////////////////////////////*/
/// @notice Validates a single createWithTimestampsLL call
/// @param params The calldata after the selector
function _validateSingle(bytes calldata params) internal view {
(ISablierLockupLinear.CreateWithTimestamps memory createParams,,) =
abi.decode(params, (ISablierLockupLinear.CreateWithTimestamps, ISablierLockupLinear.UnlockAmounts, uint40));
_validateStreamParams(
createParams.sender, createParams.recipient, createParams.cancelable, createParams.transferable
);
// Validate token is the configured token
if (address(createParams.token) != token) {
revert InvalidToken(address(createParams.token), token);
}
}
/// @notice Validates a batch createWithTimestampsLL call
/// @param params The calldata after the selector
function _validateBatch(bytes calldata params) internal view {
(address batchLockup, IERC20 batchToken, ISablierBatchLockup.CreateWithTimestampsLL[] memory batch) =
abi.decode(params, (address, IERC20, ISablierBatchLockup.CreateWithTimestampsLL[]));
// Validate lockup address
if (batchLockup != lockup) {
revert InvalidLockupAddress(batchLockup, lockup);
}
// Validate token
if (address(batchToken) != token) {
revert InvalidToken(address(batchToken), token);
}
// Validate batch is not empty
if (batch.length == 0) revert EmptyBatch();
// Validate each item in the batch
for (uint256 i = 0; i < batch.length; i++) {
_validateStreamParams(batch[i].sender, batch[i].recipient, batch[i].cancelable, batch[i].transferable);
}
}
/// @notice Validates common stream parameters
/// @param sender The stream sender (must be the safe)
/// @param recipient The stream recipient (must be in allowed list)
/// @param cancelable Whether the stream is cancelable (must be true)
/// @param transferable Whether the stream is transferable (must be true)
function _validateStreamParams(address sender, address recipient, bool cancelable, bool transferable)
internal
view
{
if (sender != safe) {
revert InvalidSender(sender, safe);
}
if (!isAllowedRecipient[recipient]) {
revert InvalidRecipient(recipient);
}
if (!cancelable) {
revert StreamMustBeCancelable();
}
if (!transferable) {
revert StreamMustBeTransferable();
}
}
/*//////////////////////////////////////////////////////////////
VIEW FUNCTIONS
//////////////////////////////////////////////////////////////*/
/// @notice Returns the number of allowed recipients
/// @return The count of allowed recipients
function getAllowedRecipientsCount() external view returns (uint256) {
return allowedRecipients.length;
}
/// @notice Returns all allowed recipients
/// @return Array of allowed recipient addresses
function getAllowedRecipients() external view returns (address[] memory) {
return allowedRecipients;
}
}// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.24;
interface IValidator {
/// @notice Validates a transaction before execution
/// @param target The address the transaction will be sent to
/// @param value The amount of ETH (in wei) that will be sent with the transaction
/// @param data The calldata that will be sent with the transaction
/// @dev This function should revert if the transaction is invalid
/// @dev This function is called before executing a transaction
function validate(address target, uint256 value, bytes calldata data) external view;
}// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.22;
import {IERC20} from "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
/// @title ISablierLockupLinear
/// @notice Creates Lockup streams with linear distribution model.
interface ISablierLockupLinear {
/// @notice Struct encapsulating the Lockup timestamps.
/// @param start The Unix timestamp for the stream's start.
/// @param end The Unix timestamp for the stream's end.
struct Timestamps {
uint40 start;
uint40 end;
}
/// @notice Struct encapsulating the parameters of the `createWithDurations` functions.
/// @param sender The address distributing the tokens, with the ability to cancel the stream. It doesn't have to be
/// the same as `msg.sender`.
/// @param recipient The address receiving the tokens, as well as the NFT owner.
/// @param depositAmount The deposit amount, denoted in units of the token's decimals.
/// @param token The contract address of the ERC-20 token to be distributed.
/// @param cancelable Indicates if the stream is cancelable.
/// @param transferable Indicates if the stream NFT is transferable.
/// @param shape An optional parameter to specify the shape of the distribution function. This helps differentiate
/// streams in the UI.
struct CreateWithDurations {
address sender;
address recipient;
uint128 depositAmount;
IERC20 token;
bool cancelable;
bool transferable;
string shape;
}
/// @notice Struct encapsulating the parameters of the `createWithTimestamps` functions.
/// @param sender The address distributing the tokens, with the ability to cancel the stream. It doesn't have to be
/// the same as `msg.sender`.
/// @param recipient The address receiving the tokens, as well as the NFT owner.
/// @param depositAmount The deposit amount, denoted in units of the token's decimals.
/// @param token The contract address of the ERC-20 token to be distributed.
/// @param cancelable Indicates if the stream is cancelable.
/// @param transferable Indicates if the stream NFT is transferable.
/// @param timestamps Struct encapsulating (i) the stream's start time and (ii) end time, both as Unix timestamps.
/// @param shape An optional parameter to specify the shape of the distribution function. This helps differentiate
/// streams in the UI.
struct CreateWithTimestamps {
address sender;
address recipient;
uint128 depositAmount;
IERC20 token;
bool cancelable;
bool transferable;
Timestamps timestamps;
string shape;
}
/// @notice Struct encapsulating the unlock amounts for the stream.
/// @dev The sum of `start` and `cliff` must be less than or equal to deposit amount. Both amounts can be zero.
/// @param start The amount to be unlocked at the start time.
/// @param cliff The amount to be unlocked at the cliff time.
struct UnlockAmounts {
// slot 0
uint128 start;
uint128 cliff;
}
/// @notice Struct encapsulating the cliff duration and the total duration used at runtime in
/// {SablierLockupLinear.createWithDurationsLL} function.
/// @param cliff The cliff duration in seconds.
/// @param total The total duration in seconds.
struct Durations {
uint40 cliff;
uint40 total;
}
/*//////////////////////////////////////////////////////////////////////////
USER-FACING STATE-CHANGING FUNCTIONS
//////////////////////////////////////////////////////////////////////////*/
/// @notice Creates a stream by setting the start time to `block.timestamp`, and the end time to
/// the sum of `block.timestamp` and `durations.total`. The stream is funded by `msg.sender` and is wrapped in an
/// ERC-721 NFT.
///
/// @dev Emits a {Transfer}, {CreateLockupLinearStream} and {MetadataUpdate} event.
///
/// Requirements:
/// - All requirements in {createWithTimestampsLL} must be met for the calculated parameters.
///
/// @param params Struct encapsulating the function parameters, which are documented in {Lockup} type.
/// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.
/// @param unlockAmounts Struct encapsulating (i) the amount to unlock at the start time and (ii) the amount to
/// unlock at the cliff time.
/// @return streamId The ID of the newly created stream.
function createWithDurationsLL(
CreateWithDurations calldata params,
UnlockAmounts calldata unlockAmounts,
Durations calldata durations
) external payable returns (uint256 streamId);
/// @notice Creates a stream with the provided start time and end time. The stream is funded by `msg.sender` and is
/// wrapped in an ERC-721 NFT.
///
/// @dev Emits a {Transfer}, {CreateLockupLinearStream} and {MetadataUpdate} event.
///
/// Notes:
/// - A cliff time of zero means there is no cliff.
/// - As long as the times are ordered, it is not an error for the start or the cliff time to be in the past.
///
/// Requirements:
/// - Must not be delegate called.
/// - `params.depositAmount` must be greater than zero.
/// - `params.timestamps.start` must be greater than zero and less than `params.timestamps.end`.
/// - If set, `cliffTime` must be greater than `params.timestamps.start` and less than
/// `params.timestamps.end`.
/// - `params.recipient` must not be the zero address.
/// - `params.sender` must not be the zero address.
/// - The sum of `params.unlockAmounts.start` and `params.unlockAmounts.cliff` must be less than or equal to
/// deposit amount.
/// - If `params.timestamps.cliff` not set, the `params.unlockAmounts.cliff` must be zero.
/// - `msg.sender` must have allowed this contract to spend at least `params.depositAmount` tokens.
/// - `params.token` must not be the native token.
/// - `params.shape.length` must not be greater than 32 characters.
///
/// @param params Struct encapsulating the function parameters, which are documented in {Lockup} type.
/// @param cliffTime The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.
/// @param unlockAmounts Struct encapsulating (i) the amount to unlock at the start time and (ii) the amount to
/// unlock at the cliff time.
/// @return streamId The ID of the newly created stream.
function createWithTimestampsLL(
CreateWithTimestamps calldata params,
UnlockAmounts calldata unlockAmounts,
uint40 cliffTime
) external payable returns (uint256 streamId);
}// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.22;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ISablierLockupLinear} from "./ISablierLockupLinear.sol";
/// @title ISablierBatchLockup
/// @notice Helper to batch create Lockup streams.
interface ISablierBatchLockup {
/// @notice A struct encapsulating all parameters of {SablierLockupLinear.createWithTimestampsLL} except for the
/// token.
struct CreateWithTimestampsLL {
address sender;
address recipient;
uint128 depositAmount;
bool cancelable;
bool transferable;
ISablierLockupLinear.Timestamps timestamps;
uint40 cliffTime;
ISablierLockupLinear.UnlockAmounts unlockAmounts;
string shape;
}
/// @notice Creates a batch of LL streams using `createWithTimestampsLL`.
///
/// @dev Requirements:
/// - There must be at least one element in `batch`.
/// - All requirements from {ISablierLockupLinear.createWithTimestampsLL} must be met for each stream.
///
/// @param lockup The address of the {SablierLockup} contract.
/// @param token The contract address of the ERC-20 token to be distributed.
/// @param batch An array of structs, each encapsulating a subset of the parameters of
/// {ISablierLockupLinear.createWithTimestampsLL}.
/// @return streamIds The ids of the newly created streams.
function createWithTimestampsLL(address lockup, IERC20 token, CreateWithTimestampsLL[] calldata batch)
external
returns (uint256[] memory streamIds);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}{
"remappings": [
"forge-std/=lib/forge-std/src/",
"@src/=src/",
"@yieldnest-vault/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/src/",
"@yieldnest-vault-script/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/script/",
"lib/openzeppelin-contracts/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/lib/openzeppelin-contracts/",
"lib/openzeppelin-contracts-upgradeable/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts-upgradeable/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/lib/openzeppelin-contracts/",
"lib/yieldnest-vault/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/",
"lib/yieldnest-flex-strategy/lib/yieldnest-vault:src/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/src/",
"lib/yieldnest-flex-strategy/lib/yieldnest-vault:script/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/script/",
"script/=lib/yieldnest-flex-strategy/script/",
"@script/=script/",
"lib/yieldnest-flex-strategy:src/=lib/yieldnest-flex-strategy/src/",
"@openzeppelin/contracts-upgradeable/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/lib/openzeppelin-contracts/contracts/",
"ds-test/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"halmos-cheatcodes/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/lib/wrapped-token/lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
"lib/forge-std/src/=lib/yieldnest-flex-strategy/lib/forge-std/src/",
"safe-smart-account/=lib/safe-smart-account/",
"wrapped-token/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/lib/wrapped-token/src/",
"yieldnest-flex-strategy/=lib/yieldnest-flex-strategy/",
"yieldnest-vault/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/",
"lib/yieldnest-vault:src/=lib/yieldnest-flex-strategy/lib/yieldnest-vault/src/"
],
"optimizer": {
"enabled": true,
"runs": 100
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_safe","type":"address"},{"internalType":"address","name":"_lockup","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"address[]","name":"_allowedRecipients","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EmptyAllowedRecipients","type":"error"},{"inputs":[],"name":"EmptyBatch","type":"error"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"InvalidFunctionSelector","type":"error"},{"inputs":[{"internalType":"address","name":"lockup","type":"address"},{"internalType":"address","name":"expectedLockup","type":"address"}],"name":"InvalidLockupAddress","type":"error"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"InvalidRecipient","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"expectedSafe","type":"address"}],"name":"InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"expectedToken","type":"address"}],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"StreamMustBeCancelable","type":"error"},{"inputs":[],"name":"StreamMustBeTransferable","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"safe","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address[]","name":"allowedRecipients","type":"address[]"}],"name":"ValidatorConfigured","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allowedRecipients","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedRecipients","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedRecipientsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAllowedRecipient","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockup","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"safe","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"validate","outputs":[],"stateMutability":"view","type":"function"}]Contract Creation Code
60e060405234801561000f575f5ffd5b5060405161115438038061115483398101604081905261002e91610262565b6001600160a01b0384166100555760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831661007c5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0382166100a35760405163d92e233d60e01b815260040160405180910390fd5b80515f036100c457604051637925cdcb60e01b815260040160405180910390fd5b6001600160a01b0380851660805283811660a052821660c0525f5b81518110156101de575f6001600160a01b03168282815181106101045761010461035e565b60200260200101516001600160a01b0316036101335760405163d92e233d60e01b815260040160405180910390fd5b60015f5f8484815181106101495761014961035e565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f6101000a81548160ff021916908315150217905550600182828151811061019a5761019a61035e565b6020908102919091018101518254600180820185555f9485529290932090920180546001600160a01b0319166001600160a01b0390931692909217909155016100df565b50816001600160a01b0316846001600160a01b03167fb30ad1a2baf26789f180c5fb852e42063934209867990c8967c5f7affcab3550836040516102229190610372565b60405180910390a3505050506103bd565b80516001600160a01b0381168114610249575f5ffd5b919050565b634e487b7160e01b5f52604160045260245ffd5b5f5f5f5f60808587031215610275575f5ffd5b61027e85610233565b935061028c60208601610233565b925061029a60408601610233565b60608601519092506001600160401b038111156102b5575f5ffd5b8501601f810187136102c5575f5ffd5b80516001600160401b038111156102de576102de61024e565b604051600582901b90603f8201601f191681016001600160401b038111828210171561030c5761030c61024e565b60405291825260208184018101929081018a841115610329575f5ffd5b6020850194505b8385101561034f5761034185610233565b815260209485019401610330565b50969995985093965050505050565b634e487b7160e01b5f52603260045260245ffd5b602080825282518282018190525f918401906040840190835b818110156103b25783516001600160a01b031683526020938401939092019160010161038b565b509095945050505050565b60805160a05160c051610d3761041d5f395f8181610175015281816103450152818161038701528181610453015261048d01525f8181608a015281816103dd015261041701525f818160ce0152818161058401526105be0152610d375ff3fe608060405234801561000f575f5ffd5b5060043610610081575f3560e01c806306490f4714610085578063186f0354146100c957806376fee249146100f0578063b124e88e14610101578063c0f7e54814610114578063eed185a814610129578063f6e23b981461015b578063fc0c546a14610170578063ffa1ad7414610197575b5f5ffd5b6100ac7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100ac7f000000000000000000000000000000000000000000000000000000000000000081565b6001546040519081526020016100c0565b6100ac61010f36600461067d565b6101c8565b61011c6101f0565b6040516100c09190610694565b61014b610137366004610706565b5f6020819052908152604090205460ff1681565b60405190151581526020016100c0565b61016e610169366004610728565b610250565b005b6100ac7f000000000000000000000000000000000000000000000000000000000000000081565b6101bb604051806040016040528060058152602001640302e322e360dc1b81525081565b6040516100c091906107ab565b600181815481106101d7575f80fd5b5f918252602090912001546001600160a01b0316905081565b6060600180548060200260200160405190810160405280929190818152602001828054801561024657602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311610228575b5050505050905090565b600481101561027d576040516310cb7cf160e21b8152610274905f906004016107e0565b60405180910390fd5b5f61028b60048284866107f5565b6102949161081c565b9050638b2dec1b60e01b6001600160e01b03198216016102c8576102c36102be83600481876107f5565b610317565b610310565b63bff2533f60e01b6001600160e01b03198216016102f5576102c36102f083600481876107f5565b6103c6565b806040516310cb7cf160e21b815260040161027491906107e0565b5050505050565b5f61032482840184610a17565b50509050610343815f0151826020015183608001518460a00151610582565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681606001516001600160a01b0316146103c15780606001517f0000000000000000000000000000000000000000000000000000000000000000604051630fc746a160e01b8152600401610274929190610b1d565b505050565b5f80806103d584860186610b37565b9250925092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03161461045157827f00000000000000000000000000000000000000000000000000000000000000006040516308cd70d960e21b8152600401610274929190610b1d565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316146104c757817f0000000000000000000000000000000000000000000000000000000000000000604051630fc746a160e01b8152600401610274929190610b1d565b80515f036104e85760405163c2e5347d60e01b815260040160405180910390fd5b5f5b815181101561057a5761057282828151811061050857610508610ced565b60200260200101515f015183838151811061052557610525610ced565b60200260200101516020015184848151811061054357610543610ced565b60200260200101516060015185858151811061056157610561610ced565b602002602001015160800151610582565b6001016104ea565b505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b0316146105f857837f000000000000000000000000000000000000000000000000000000000000000060405163708986dd60e11b8152600401610274929190610b1d565b6001600160a01b0383165f9081526020819052604090205460ff1661063b57604051630bc2c5df60e11b81526001600160a01b0384166004820152602401610274565b8161065957604051639d6bce1360e01b815260040160405180910390fd5b806106775760405163d69f758760e01b815260040160405180910390fd5b50505050565b5f6020828403121561068d575f5ffd5b5035919050565b602080825282518282018190525f918401906040840190835b818110156106d45783516001600160a01b03168352602093840193909201916001016106ad565b509095945050505050565b6001600160a01b03811681146106f3575f5ffd5b50565b8035610701816106df565b919050565b5f60208284031215610716575f5ffd5b8135610721816106df565b9392505050565b5f5f5f5f6060858703121561073b575f5ffd5b8435610746816106df565b93506020850135925060408501356001600160401b03811115610767575f5ffd5b8501601f81018713610777575f5ffd5b80356001600160401b0381111561078c575f5ffd5b87602082840101111561079d575f5ffd5b949793965060200194505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b6001600160e01b031991909116815260200190565b5f5f85851115610803575f5ffd5b8386111561080f575f5ffd5b5050820193919092039150565b80356001600160e01b0319811690600484101561084d576001600160e01b0319600485900360031b81901b82161691505b5092915050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b038111828210171561088a5761088a610854565b60405290565b60405161010081016001600160401b038111828210171561088a5761088a610854565b60405161012081016001600160401b038111828210171561088a5761088a610854565b604051601f8201601f191681016001600160401b03811182821017156108fe576108fe610854565b604052919050565b80356001600160801b0381168114610701575f5ffd5b80358015158114610701575f5ffd5b803564ffffffffff81168114610701575f5ffd5b5f6040828403121561094f575f5ffd5b610957610868565b90506109628261092b565b81526109706020830161092b565b602082015292915050565b5f82601f83011261098a575f5ffd5b81356001600160401b038111156109a3576109a3610854565b6109b6601f8201601f19166020016108d6565b8181528460208386010111156109ca575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f604082840312156109f6575f5ffd5b6109fe610868565b9050610a0982610906565b815261097060208301610906565b5f5f5f60808486031215610a29575f5ffd5b83356001600160401b03811115610a3e575f5ffd5b84016101208187031215610a50575f5ffd5b610a58610890565b610a61826106f6565b8152610a6f602083016106f6565b6020820152610a8060408301610906565b6040820152610a91606083016106f6565b6060820152610aa26080830161091c565b6080820152610ab360a0830161091c565b60a0820152610ac58760c0840161093f565b60c08201526101008201356001600160401b03811115610ae3575f5ffd5b610aef8882850161097b565b60e0830152509350610b06905085602086016109e6565b9150610b146060850161092b565b90509250925092565b6001600160a01b0392831681529116602082015260400190565b5f5f5f60608486031215610b49575f5ffd5b8335610b54816106df565b92506020840135610b64816106df565b915060408401356001600160401b03811115610b7e575f5ffd5b8401601f81018613610b8e575f5ffd5b80356001600160401b03811115610ba757610ba7610854565b8060051b610bb7602082016108d6565b91825260208184018101929081019089841115610bd2575f5ffd5b6020850192505b83831015610cde5782356001600160401b03811115610bf6575f5ffd5b8501610160818c03601f19011215610c0c575f5ffd5b610c146108b3565b610c20602083016106f6565b8152610c2e604083016106f6565b6020820152610c3f60608301610906565b6040820152610c506080830161091c565b6060820152610c6160a0830161091c565b6080820152610c738c60c0840161093f565b60a0820152610c85610100830161092b565b60c0820152610c988c61012084016109e6565b60e08201526101608201356001600160401b03811115610cb6575f5ffd5b610cc58d60208386010161097b565b6101008301525083525060209283019290910190610bd9565b80955050505050509250925092565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220d958cf188e650efc193f4c962b4897611d62e5e7d990eeff0dc77526de33a4aa64736f6c634300081c0033000000000000000000000000b34e69c23df216334496dffd455618249e6bbfa9000000000000000000000000cf8ce57fa442ba50acbc57147a62ad03873ffa73000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000bac19fd66262629eea13f1fd36ba9ae654bdfc76
Deployed Bytecode
0x608060405234801561000f575f5ffd5b5060043610610081575f3560e01c806306490f4714610085578063186f0354146100c957806376fee249146100f0578063b124e88e14610101578063c0f7e54814610114578063eed185a814610129578063f6e23b981461015b578063fc0c546a14610170578063ffa1ad7414610197575b5f5ffd5b6100ac7f000000000000000000000000cf8ce57fa442ba50acbc57147a62ad03873ffa7381565b6040516001600160a01b0390911681526020015b60405180910390f35b6100ac7f000000000000000000000000b34e69c23df216334496dffd455618249e6bbfa981565b6001546040519081526020016100c0565b6100ac61010f36600461067d565b6101c8565b61011c6101f0565b6040516100c09190610694565b61014b610137366004610706565b5f6020819052908152604090205460ff1681565b60405190151581526020016100c0565b61016e610169366004610728565b610250565b005b6100ac7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b6101bb604051806040016040528060058152602001640302e322e360dc1b81525081565b6040516100c091906107ab565b600181815481106101d7575f80fd5b5f918252602090912001546001600160a01b0316905081565b6060600180548060200260200160405190810160405280929190818152602001828054801561024657602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311610228575b5050505050905090565b600481101561027d576040516310cb7cf160e21b8152610274905f906004016107e0565b60405180910390fd5b5f61028b60048284866107f5565b6102949161081c565b9050638b2dec1b60e01b6001600160e01b03198216016102c8576102c36102be83600481876107f5565b610317565b610310565b63bff2533f60e01b6001600160e01b03198216016102f5576102c36102f083600481876107f5565b6103c6565b806040516310cb7cf160e21b815260040161027491906107e0565b5050505050565b5f61032482840184610a17565b50509050610343815f0151826020015183608001518460a00151610582565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b031681606001516001600160a01b0316146103c15780606001517f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48604051630fc746a160e01b8152600401610274929190610b1d565b505050565b5f80806103d584860186610b37565b9250925092507f000000000000000000000000cf8ce57fa442ba50acbc57147a62ad03873ffa736001600160a01b0316836001600160a01b03161461045157827f000000000000000000000000cf8ce57fa442ba50acbc57147a62ad03873ffa736040516308cd70d960e21b8152600401610274929190610b1d565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316826001600160a01b0316146104c757817f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48604051630fc746a160e01b8152600401610274929190610b1d565b80515f036104e85760405163c2e5347d60e01b815260040160405180910390fd5b5f5b815181101561057a5761057282828151811061050857610508610ced565b60200260200101515f015183838151811061052557610525610ced565b60200260200101516020015184848151811061054357610543610ced565b60200260200101516060015185858151811061056157610561610ced565b602002602001015160800151610582565b6001016104ea565b505050505050565b7f000000000000000000000000b34e69c23df216334496dffd455618249e6bbfa96001600160a01b0316846001600160a01b0316146105f857837f000000000000000000000000b34e69c23df216334496dffd455618249e6bbfa960405163708986dd60e11b8152600401610274929190610b1d565b6001600160a01b0383165f9081526020819052604090205460ff1661063b57604051630bc2c5df60e11b81526001600160a01b0384166004820152602401610274565b8161065957604051639d6bce1360e01b815260040160405180910390fd5b806106775760405163d69f758760e01b815260040160405180910390fd5b50505050565b5f6020828403121561068d575f5ffd5b5035919050565b602080825282518282018190525f918401906040840190835b818110156106d45783516001600160a01b03168352602093840193909201916001016106ad565b509095945050505050565b6001600160a01b03811681146106f3575f5ffd5b50565b8035610701816106df565b919050565b5f60208284031215610716575f5ffd5b8135610721816106df565b9392505050565b5f5f5f5f6060858703121561073b575f5ffd5b8435610746816106df565b93506020850135925060408501356001600160401b03811115610767575f5ffd5b8501601f81018713610777575f5ffd5b80356001600160401b0381111561078c575f5ffd5b87602082840101111561079d575f5ffd5b949793965060200194505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b6001600160e01b031991909116815260200190565b5f5f85851115610803575f5ffd5b8386111561080f575f5ffd5b5050820193919092039150565b80356001600160e01b0319811690600484101561084d576001600160e01b0319600485900360031b81901b82161691505b5092915050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b038111828210171561088a5761088a610854565b60405290565b60405161010081016001600160401b038111828210171561088a5761088a610854565b60405161012081016001600160401b038111828210171561088a5761088a610854565b604051601f8201601f191681016001600160401b03811182821017156108fe576108fe610854565b604052919050565b80356001600160801b0381168114610701575f5ffd5b80358015158114610701575f5ffd5b803564ffffffffff81168114610701575f5ffd5b5f6040828403121561094f575f5ffd5b610957610868565b90506109628261092b565b81526109706020830161092b565b602082015292915050565b5f82601f83011261098a575f5ffd5b81356001600160401b038111156109a3576109a3610854565b6109b6601f8201601f19166020016108d6565b8181528460208386010111156109ca575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f604082840312156109f6575f5ffd5b6109fe610868565b9050610a0982610906565b815261097060208301610906565b5f5f5f60808486031215610a29575f5ffd5b83356001600160401b03811115610a3e575f5ffd5b84016101208187031215610a50575f5ffd5b610a58610890565b610a61826106f6565b8152610a6f602083016106f6565b6020820152610a8060408301610906565b6040820152610a91606083016106f6565b6060820152610aa26080830161091c565b6080820152610ab360a0830161091c565b60a0820152610ac58760c0840161093f565b60c08201526101008201356001600160401b03811115610ae3575f5ffd5b610aef8882850161097b565b60e0830152509350610b06905085602086016109e6565b9150610b146060850161092b565b90509250925092565b6001600160a01b0392831681529116602082015260400190565b5f5f5f60608486031215610b49575f5ffd5b8335610b54816106df565b92506020840135610b64816106df565b915060408401356001600160401b03811115610b7e575f5ffd5b8401601f81018613610b8e575f5ffd5b80356001600160401b03811115610ba757610ba7610854565b8060051b610bb7602082016108d6565b91825260208184018101929081019089841115610bd2575f5ffd5b6020850192505b83831015610cde5782356001600160401b03811115610bf6575f5ffd5b8501610160818c03601f19011215610c0c575f5ffd5b610c146108b3565b610c20602083016106f6565b8152610c2e604083016106f6565b6020820152610c3f60608301610906565b6040820152610c506080830161091c565b6060820152610c6160a0830161091c565b6080820152610c738c60c0840161093f565b60a0820152610c85610100830161092b565b60c0820152610c988c61012084016109e6565b60e08201526101608201356001600160401b03811115610cb6575f5ffd5b610cc58d60208386010161097b565b6101008301525083525060209283019290910190610bd9565b80955050505050509250925092565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220d958cf188e650efc193f4c962b4897611d62e5e7d990eeff0dc77526de33a4aa64736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b34e69c23df216334496dffd455618249e6bbfa9000000000000000000000000cf8ce57fa442ba50acbc57147a62ad03873ffa73000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000bac19fd66262629eea13f1fd36ba9ae654bdfc76
-----Decoded View---------------
Arg [0] : _safe (address): 0xb34E69c23Df216334496DFFd455618249E6bbFa9
Arg [1] : _lockup (address): 0xcF8ce57fa442ba50aCbC57147a62aD03873FfA73
Arg [2] : _token (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [3] : _allowedRecipients (address[]): 0xbAC19FD66262629eEA13F1fd36ba9ae654bDfc76
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000b34e69c23df216334496dffd455618249e6bbfa9
Arg [1] : 000000000000000000000000cf8ce57fa442ba50acbc57147a62ad03873ffa73
Arg [2] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [5] : 000000000000000000000000bac19fd66262629eea13f1fd36ba9ae654bdfc76
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.