Source Code
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
There are no matching entriesUpdate your filters to view other transactions | |||||||||
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
MegaPreDepositVaultRefund
Compiler Version
v0.8.30+commit.73712a01
Optimization Enabled:
No with 200 runs
Other Settings:
prague EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
import "./interface/IMegaUSDmPreDepositVault.sol";
interface IUSDC is IERC20 {
function isBlacklisted(address account) external view returns (bool);
}
contract MegaPreDepositVaultRefund is Ownable, AccessControl, ReentrancyGuardTransient {
using SafeERC20 for IERC20;
using SafeERC20 for IUSDC;
// ============ Roles ============
bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
// ============ Immutable Variables ============
IMegaUSDmPreDeposit public immutable vault;
IUSDC public immutable token;
// ============ State Variables ============
uint256 public lastProcessedIndex;
uint256 public lastProcessedAmount;
uint256 public refundedAmount;
// ============ Events ============
event RefundProcessed(address indexed user, uint256 amount, uint256 index, bool isFullRefund);
event BatchRefundCompleted(uint256 startIndex, uint256 endIndex, uint256 totalRefunded, uint256 lastProcessedAmount);
event EmergencyWithdraw(address indexed token, address indexed to, uint256 amount);
event IndicesSkipped(uint256 startIndex);
// ============ Errors ============
error SequenceMismatch(uint256 expected, uint256 actual);
error NoUsersToRefund();
error ZeroAddress();
error ZeroAmount();
error ZeroBalance();
error UserNotBlacklisted(address user);
// ============ Constructor ============
constructor(address _vault, address _owner, address _executor) Ownable(_owner) {
if (_vault == address(0)) revert ZeroAddress();
if (_owner == address(0)) revert ZeroAddress();
if (_executor == address(0)) revert ZeroAddress();
vault = IMegaUSDmPreDeposit(_vault);
token = IUSDC(address(vault.usdc()));
// Grant EXECUTOR_ROLE to the specified executor
_grantRole(EXECUTOR_ROLE, _executor);
// Set owner as the admin of EXECUTOR_ROLE
_setRoleAdmin(EXECUTOR_ROLE, DEFAULT_ADMIN_ROLE);
// Grant DEFAULT_ADMIN_ROLE to the owner
_grantRole(DEFAULT_ADMIN_ROLE, _owner);
}
// ============ External Functions ============
/// @notice Performs batch refund to users from the vault
/// @dev Only callable by addresses with EXECUTOR_ROLE
/// @dev Automatically uses lastProcessedIndex and lastProcessedAmount as the starting point
/// @dev Refunds up to count users with all the remaining balance in the contract
/// @dev Supports partial refunds - if a user needs more than available balance, they get partial refund
/// @param count Maximum number of users to refund in this batch
function batchRefund(uint256 count) external onlyRole(EXECUTOR_ROLE) nonReentrant {
if (count == 0) {
revert NoUsersToRefund();
}
uint256 startIndex = lastProcessedIndex;
uint256 availableBalance = token.balanceOf(address(this));
if (availableBalance == 0) {
revert ZeroBalance();
}
// Get users from vault
IMegaUSDmPreDeposit.UserView[] memory users = vault.getUsers(startIndex, count);
if (users.length == 0) {
revert NoUsersToRefund();
}
uint256 totalTransferred = 0;
uint256 remainingBalance = availableBalance;
uint256 i = 0;
// Process each user until we run out of balance or users
while (i < users.length && remainingBalance > 0) {
address user = users[i].user;
uint256 userTotalAmount = users[i].amount;
uint256 userIndex = users[i].index;
// Verify index sequence
if (userIndex != startIndex + i) {
revert SequenceMismatch(startIndex + i, userIndex);
}
// Calculate remaining amount needed for this user
uint256 remainingNeeded = userTotalAmount - lastProcessedAmount;
// Determine how much to transfer to this user
uint256 amountToTransfer = remainingNeeded <= remainingBalance ? remainingNeeded : remainingBalance;
// Update state variables (Effects) - following CEI pattern
totalTransferred += amountToTransfer;
remainingBalance -= amountToTransfer;
uint256 newProcessedAmount = lastProcessedAmount + amountToTransfer;
// Determine if this is a full or partial refund
bool isFullRefund = newProcessedAmount >= userTotalAmount;
if (isFullRefund) {
// Move to next user
lastProcessedAmount = 0;
lastProcessedIndex = userIndex + 1;
i++;
} else {
// Partial refund, stay on same user for next batch
lastProcessedAmount = newProcessedAmount;
}
// Transfer tokens to user (Interaction)
token.safeTransfer(user, amountToTransfer);
emit RefundProcessed(user, amountToTransfer, userIndex, isFullRefund);
// Break if partial refund (used all available balance)
if (!isFullRefund) {
break;
}
}
// Update total refunded amount
refundedAmount += totalTransferred;
emit BatchRefundCompleted(startIndex, lastProcessedIndex, totalTransferred, lastProcessedAmount);
}
/// @notice Skip one index to resume refund process at the next position
/// @dev Admin-only function to handle edge cases where certain indices need to be skipped
/// @dev Resets lastProcessedAmount to 0 when skipping
/// @dev Requires that the user being skipped is blacklisted
function skipRefund() external onlyOwner {
uint256 startIndex = lastProcessedIndex;
// Get the user at the current index
IMegaUSDmPreDeposit.UserView[] memory users = vault.getUsers(startIndex, 1);
if (users.length == 0) {
revert NoUsersToRefund();
}
address user = users[0].user;
// Check if the user is blacklisted
if (!token.isBlacklisted(user)) {
revert UserNotBlacklisted(user);
}
lastProcessedIndex += 1;
lastProcessedAmount = 0;
emit IndicesSkipped(startIndex);
}
/// @notice Emergency withdraw function to recover any stuck tokens
/// @param tokenAddress Address of the token to withdraw (can be any ERC20)
/// @param to Recipient address
/// @param amount Amount to withdraw
function emergencyWithdraw(address tokenAddress, address to, uint256 amount) external onlyOwner {
if (tokenAddress == address(0)) revert ZeroAddress();
if (to == address(0)) revert ZeroAddress();
if (amount == 0) revert ZeroAmount();
IERC20(tokenAddress).safeTransfer(to, amount);
emit EmergencyWithdraw(tokenAddress, to, amount);
}
/// @notice Get the contract's token balance
/// @return balance The token balance
function getBalance() external view returns (uint256) {
return token.balanceOf(address(this));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
if (!_safeTransfer(token, to, value, true)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
if (!_safeTransferFrom(token, from, to, value, true)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _safeTransfer(token, to, value, false);
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _safeTransferFrom(token, from, to, value, false);
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
if (!_safeApprove(token, spender, value, false)) {
if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));
if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Oppositely, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity `token.transfer(to, value)` call, relaxing the requirement on the return value: the
* return value is optional (but if data is returned, it must not be false).
*
* @param token The token targeted by the call.
* @param to The recipient of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {
bytes4 selector = IERC20.transfer.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(to, shr(96, not(0))))
mstore(0x24, value)
success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0x00, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
}
}
/**
* @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, relaxing the requirement on the return
* value: the return value is optional (but if data is returned, it must not be false).
*
* @param token The token targeted by the call.
* @param from The sender of the tokens
* @param to The recipient of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value,
bool bubble
) private returns (bool success) {
bytes4 selector = IERC20.transferFrom.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(from, shr(96, not(0))))
mstore(0x24, and(to, shr(96, not(0))))
mstore(0x44, value)
success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0x00, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
mstore(0x60, 0)
}
}
/**
* @dev Imitates a Solidity `token.approve(spender, value)` call, relaxing the requirement on the return value:
* the return value is optional (but if data is returned, it must not be false).
*
* @param token The token targeted by the call.
* @param spender The spender of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {
bytes4 selector = IERC20.approve.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(spender, shr(96, not(0))))
mstore(0x24, value)
success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0x00, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../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.
*
* The initial owner is set to the address provided by the deployer. 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;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @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 {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling 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 {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_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 v5.4.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {IERC165, ERC165} from "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
return _roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.5.0) (utils/ReentrancyGuardTransient.sol)
pragma solidity ^0.8.24;
import {TransientSlot} from "./TransientSlot.sol";
/**
* @dev Variant of {ReentrancyGuard} that uses transient storage.
*
* NOTE: This variant only works on networks where EIP-1153 is available.
*
* _Available since v5.1._
*
* @custom:stateless
*/
abstract contract ReentrancyGuardTransient {
using TransientSlot for *;
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant REENTRANCY_GUARD_STORAGE =
0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
/**
* @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();
}
/**
* @dev A `view` only version of {nonReentrant}. Use to block view functions
* from being called, preventing reading from inconsistent contract state.
*
* CAUTION: This is a "view" modifier and does not change the reentrancy
* status. Use it only on view functions. For payable or non-payable functions,
* use the standard {nonReentrant} modifier instead.
*/
modifier nonReentrantView() {
_nonReentrantBeforeView();
_;
}
function _nonReentrantBeforeView() private view {
if (_reentrancyGuardEntered()) {
revert ReentrancyGuardReentrantCall();
}
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, REENTRANCY_GUARD_STORAGE.asBoolean().tload() will be false
_nonReentrantBeforeView();
// Any calls to nonReentrant after this point will fail
_reentrancyGuardStorageSlot().asBoolean().tstore(true);
}
function _nonReentrantAfter() private {
_reentrancyGuardStorageSlot().asBoolean().tstore(false);
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _reentrancyGuardStorageSlot().asBoolean().tload();
}
function _reentrancyGuardStorageSlot() internal pure virtual returns (bytes32) {
return REENTRANCY_GUARD_STORAGE;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IMegaUSDmPreDeposit {
// ============ Structs ============
struct UserView {
bytes16 entityID; // Entity ID
address user; // Wallet address
uint256 amount; // Deposit amount
uint256 index; // Index in the collection
}
// User entity
struct UserEntity {
address user; // Bound wallet address
uint256 deposits; // Total deposit amount of this entity
}
function usdc() external view returns (IERC20);
function getUserCount() external view returns (uint256);
function getUsers(uint256 startIndex, uint256 count) external view returns (UserView[] memory users);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/IAccessControl.sol)
pragma solidity >=0.8.4;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted to signal this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).
* Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (utils/TransientSlot.sol)
// This file was procedurally generated from scripts/generate/templates/TransientSlot.js.
pragma solidity ^0.8.24;
/**
* @dev Library for reading and writing value-types to specific transient storage slots.
*
* Transient slots are often used to store temporary values that are removed after the current transaction.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* * Example reading and writing values using transient storage:
* ```solidity
* contract Lock {
* using TransientSlot for *;
*
* // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.
* bytes32 internal constant _LOCK_SLOT = 0xf4678858b2b588224636b8522b729e7722d32fc491da849ed75b3fdf3c84f542;
*
* modifier locked() {
* require(!_LOCK_SLOT.asBoolean().tload());
*
* _LOCK_SLOT.asBoolean().tstore(true);
* _;
* _LOCK_SLOT.asBoolean().tstore(false);
* }
* }
* ```
*
* TIP: Consider using this library along with {SlotDerivation}.
*/
library TransientSlot {
/**
* @dev UDVT that represents a slot holding an address.
*/
type AddressSlot is bytes32;
/**
* @dev Cast an arbitrary slot to a AddressSlot.
*/
function asAddress(bytes32 slot) internal pure returns (AddressSlot) {
return AddressSlot.wrap(slot);
}
/**
* @dev UDVT that represents a slot holding a bool.
*/
type BooleanSlot is bytes32;
/**
* @dev Cast an arbitrary slot to a BooleanSlot.
*/
function asBoolean(bytes32 slot) internal pure returns (BooleanSlot) {
return BooleanSlot.wrap(slot);
}
/**
* @dev UDVT that represents a slot holding a bytes32.
*/
type Bytes32Slot is bytes32;
/**
* @dev Cast an arbitrary slot to a Bytes32Slot.
*/
function asBytes32(bytes32 slot) internal pure returns (Bytes32Slot) {
return Bytes32Slot.wrap(slot);
}
/**
* @dev UDVT that represents a slot holding a uint256.
*/
type Uint256Slot is bytes32;
/**
* @dev Cast an arbitrary slot to a Uint256Slot.
*/
function asUint256(bytes32 slot) internal pure returns (Uint256Slot) {
return Uint256Slot.wrap(slot);
}
/**
* @dev UDVT that represents a slot holding a int256.
*/
type Int256Slot is bytes32;
/**
* @dev Cast an arbitrary slot to a Int256Slot.
*/
function asInt256(bytes32 slot) internal pure returns (Int256Slot) {
return Int256Slot.wrap(slot);
}
/**
* @dev Load the value held at location `slot` in transient storage.
*/
function tload(AddressSlot slot) internal view returns (address value) {
assembly ("memory-safe") {
value := tload(slot)
}
}
/**
* @dev Store `value` at location `slot` in transient storage.
*/
function tstore(AddressSlot slot, address value) internal {
assembly ("memory-safe") {
tstore(slot, value)
}
}
/**
* @dev Load the value held at location `slot` in transient storage.
*/
function tload(BooleanSlot slot) internal view returns (bool value) {
assembly ("memory-safe") {
value := tload(slot)
}
}
/**
* @dev Store `value` at location `slot` in transient storage.
*/
function tstore(BooleanSlot slot, bool value) internal {
assembly ("memory-safe") {
tstore(slot, value)
}
}
/**
* @dev Load the value held at location `slot` in transient storage.
*/
function tload(Bytes32Slot slot) internal view returns (bytes32 value) {
assembly ("memory-safe") {
value := tload(slot)
}
}
/**
* @dev Store `value` at location `slot` in transient storage.
*/
function tstore(Bytes32Slot slot, bytes32 value) internal {
assembly ("memory-safe") {
tstore(slot, value)
}
}
/**
* @dev Load the value held at location `slot` in transient storage.
*/
function tload(Uint256Slot slot) internal view returns (uint256 value) {
assembly ("memory-safe") {
value := tload(slot)
}
}
/**
* @dev Store `value` at location `slot` in transient storage.
*/
function tstore(Uint256Slot slot, uint256 value) internal {
assembly ("memory-safe") {
tstore(slot, value)
}
}
/**
* @dev Load the value held at location `slot` in transient storage.
*/
function tload(Int256Slot slot) internal view returns (int256 value) {
assembly ("memory-safe") {
value := tload(slot)
}
}
/**
* @dev Store `value` at location `slot` in transient storage.
*/
function tstore(Int256Slot slot, int256 value) internal {
assembly ("memory-safe") {
tstore(slot, value)
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": false,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "prague",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_executor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"NoUsersToRefund","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"actual","type":"uint256"}],"name":"SequenceMismatch","type":"error"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"UserNotBlacklisted","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"inputs":[],"name":"ZeroBalance","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"startIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalRefunded","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastProcessedAmount","type":"uint256"}],"name":"BatchRefundCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"startIndex","type":"uint256"}],"name":"IndicesSkipped","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":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isFullRefund","type":"bool"}],"name":"RefundProcessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXECUTOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"batchRefund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastProcessedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastProcessedIndex","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":"refundedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"skipRefund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IUSDC","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract IMegaUSDmPreDeposit","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60c060405234801561000f575f5ffd5b506040516125d43803806125d483398181016040528101906100319190610630565b815f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100a2575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610099919061068f565b60405180910390fd5b6100b18161033560201b60201c565b505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610117576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361017c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101e1576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505060805173ffffffffffffffffffffffffffffffffffffffff16633e413bee6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610260573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061028491906106e3565b73ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250506102e77fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63826103f660201b60201c565b5061031a7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e635f5f1b6104eb60201b60201c565b61032c5f5f1b836103f660201b60201c565b5050505061070e565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f610407838361054a60201b60201c565b6104e1576001805f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061047e6105ae60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600190506104e5565b5f90505b92915050565b5f6104fb836105b560201b60201c565b90508160015f8581526020019081526020015f20600101819055508181847fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff60405160405180910390a4505050565b5f60015f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f33905090565b5f60015f8381526020019081526020015f20600101549050919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6105ff826105d6565b9050919050565b61060f816105f5565b8114610619575f5ffd5b50565b5f8151905061062a81610606565b92915050565b5f5f5f60608486031215610647576106466105d2565b5b5f6106548682870161061c565b93505060206106658682870161061c565b92505060406106768682870161061c565b9150509250925092565b610689816105f5565b82525050565b5f6020820190506106a25f830184610680565b92915050565b5f6106b2826105f5565b9050919050565b6106c2816106a8565b81146106cc575f5ffd5b50565b5f815190506106dd816106b9565b92915050565b5f602082840312156106f8576106f76105d2565b5b5f610705848285016106cf565b91505092915050565b60805160a051611e7b6107595f395f8181610428015281816105f70152818161091f01528181610dbc0152610f9901525f81816106cb01528181610cc00152610f750152611e7b5ff3fe608060405234801561000f575f5ffd5b506004361061012a575f3560e01c806391d14854116100ab578063e63ea4081161006f578063e63ea4081461030a578063ec2d3c0214610326578063f2fde38b14610330578063fbfa77cf1461034c578063fc0c546a1461036a5761012a565b806391d1485414610264578063a217fddf14610294578063ad7c6ed1146102b2578063c76bda86146102d0578063d547741f146102ee5761012a565b80633009a609116100f25780633009a609146101e657806336568abe146102045780634b5fb9c214610220578063715018a61461023c5780638da5cb5b146102465761012a565b806301ffc9a71461012e57806307bd02651461015e57806312065fe01461017c578063248a9ca31461019a5780632f2ff15d146101ca575b5f5ffd5b610148600480360381019061014391906115b9565b610388565b60405161015591906115fe565b60405180910390f35b610166610401565b604051610173919061162f565b60405180910390f35b610184610425565b6040516101919190611660565b60405180910390f35b6101b460048036038101906101af91906116a3565b6104c3565b6040516101c1919061162f565b60405180910390f35b6101e460048036038101906101df9190611728565b6104e0565b005b6101ee610502565b6040516101fb9190611660565b60405180910390f35b61021e60048036038101906102199190611728565b610508565b005b61023a60048036038101906102359190611790565b610583565b005b610244610a3d565b005b61024e610a50565b60405161025b91906117ca565b60405180910390f35b61027e60048036038101906102799190611728565b610a77565b60405161028b91906115fe565b60405180910390f35b61029c610adb565b6040516102a9919061162f565b60405180910390f35b6102ba610ae1565b6040516102c79190611660565b60405180910390f35b6102d8610ae7565b6040516102e59190611660565b60405180910390f35b61030860048036038101906103039190611728565b610aed565b005b610324600480360381019061031f91906117e3565b610b0f565b005b61032e610caf565b005b61034a60048036038101906103459190611833565b610eef565b005b610354610f73565b60405161036191906118b9565b60405180910390f35b610372610f97565b60405161037f91906118f2565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103fa57506103f982610fbb565b5b9050919050565b7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161047f91906117ca565b602060405180830381865afa15801561049a573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104be919061191f565b905090565b5f60015f8381526020019081526020015f20600101549050919050565b6104e9826104c3565b6104f281611024565b6104fc8383611038565b50505050565b60025481565b610510611121565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610574576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61057e8282611128565b505050565b7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e636105ad81611024565b6105b5611212565b5f82036105ee576040517f8b4f6fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60025490505f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161064e91906117ca565b602060405180830381865afa158015610669573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061068d919061191f565b90505f81036106c8576040517f669567ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166345982a6684876040518363ffffffff1660e01b815260040161072492919061194a565b5f60405180830381865afa15801561073e573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906107669190611ba3565b90505f8151036107a2576040517f8b4f6fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f90505f8390505f5f90505b8351811080156107be57505f82115b156109d2575f8482815181106107d7576107d6611bea565b5b60200260200101516020015190505f8583815181106107f9576107f8611bea565b5b60200260200101516040015190505f86848151811061081b5761081a611bea565b5b602002602001015160600151905083896108359190611c44565b81146108855783896108479190611c44565b816040517f3efab60600000000000000000000000000000000000000000000000000000000815260040161087c92919061194a565b60405180910390fd5b5f600354836108949190611c77565b90505f868211156108a557866108a7565b815b905080886108b59190611c44565b975080876108c39190611c77565b96505f816003546108d49190611c44565b90505f8582101590508015610910575f6003819055506001856108f79190611c44565b600281905550878061090890611caa565b985050610918565b816003819055505b61096387847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661123f9092919063ffffffff16565b8673ffffffffffffffffffffffffffffffffffffffff167f52da1513e99058a8135194d646824e865501f706eb0181ecd7a8e526d8a401118487846040516109ad93929190611cf1565b60405180910390a2806109c657505050505050506109d2565b505050505050506107af565b8260045f8282546109e39190611c44565b925050819055507f059092cb0d34e7f4af801acb970ca7f00bc4138c07427a5bb4b64394a736c8da8660025485600354604051610a239493929190611d26565b60405180910390a1505050505050610a39611292565b5050565b610a456112b6565b610a4e5f61133d565b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f60015f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f1b81565b60045481565b60035481565b610af6826104c3565b610aff81611024565b610b098383611128565b50505050565b610b176112b6565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b7c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610be1576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8103610c1a576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c4582828573ffffffffffffffffffffffffffffffffffffffff1661123f9092919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ff24ef89f38eadc1bde50701ad6e4d6d11a2dc24f7cf834a486991f388332850483604051610ca29190611660565b60405180910390a3505050565b610cb76112b6565b5f60025490505f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166345982a668360016040518363ffffffff1660e01b8152600401610d1a929190611da2565b5f60405180830381865afa158015610d34573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610d5c9190611ba3565b90505f815103610d98576040517f8b4f6fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f815f81518110610dac57610dab611bea565b5b60200260200101516020015190507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fe575a87826040518263ffffffff1660e01b8152600401610e1391906117ca565b602060405180830381865afa158015610e2e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e529190611df3565b610e9357806040517f36558c81000000000000000000000000000000000000000000000000000000008152600401610e8a91906117ca565b60405180910390fd5b600160025f828254610ea59190611c44565b925050819055505f6003819055507f1d6e89e7710bcd9a69582f2a65e41027d0d6e46da22ad9255d6f2a2a9655b60183604051610ee29190611660565b60405180910390a1505050565b610ef76112b6565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610f67575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610f5e91906117ca565b60405180910390fd5b610f708161133d565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61103581611030611121565b6113fe565b50565b5f6110438383610a77565b611117576001805f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506110b4611121565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001905061111b565b5f90505b92915050565b5f33905090565b5f6111338383610a77565b15611208575f60015f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506111a5611121565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a46001905061120c565b5f90505b92915050565b61121a61144f565b61123d600161122f61122a611490565b6114b9565b6114c290919063ffffffff16565b565b61124c83838360016114c9565b61128d57826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161128491906117ca565b60405180910390fd5b505050565b6112b45f6112a66112a1611490565b6114b9565b6114c290919063ffffffff16565b565b6112be611121565b73ffffffffffffffffffffffffffffffffffffffff166112dc610a50565b73ffffffffffffffffffffffffffffffffffffffff161461133b576112ff611121565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161133291906117ca565b60405180910390fd5b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6114088282610a77565b61144b5780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401611442929190611e1e565b60405180910390fd5b5050565b61145761152b565b1561148e576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005f1b905090565b5f819050919050565b80825d5050565b5f5f63a9059cbb60e01b9050604051815f525f1960601c86166004528460245260205f60445f5f8b5af1925060015f5114831661151d578383151615611511573d5f823e3d81fd5b5f873b113d1516831692505b806040525050949350505050565b5f61154461153f61153a611490565b6114b9565b611549565b905090565b5f815c9050919050565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61159881611564565b81146115a2575f5ffd5b50565b5f813590506115b38161158f565b92915050565b5f602082840312156115ce576115cd61155c565b5b5f6115db848285016115a5565b91505092915050565b5f8115159050919050565b6115f8816115e4565b82525050565b5f6020820190506116115f8301846115ef565b92915050565b5f819050919050565b61162981611617565b82525050565b5f6020820190506116425f830184611620565b92915050565b5f819050919050565b61165a81611648565b82525050565b5f6020820190506116735f830184611651565b92915050565b61168281611617565b811461168c575f5ffd5b50565b5f8135905061169d81611679565b92915050565b5f602082840312156116b8576116b761155c565b5b5f6116c58482850161168f565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6116f7826116ce565b9050919050565b611707816116ed565b8114611711575f5ffd5b50565b5f81359050611722816116fe565b92915050565b5f5f6040838503121561173e5761173d61155c565b5b5f61174b8582860161168f565b925050602061175c85828601611714565b9150509250929050565b61176f81611648565b8114611779575f5ffd5b50565b5f8135905061178a81611766565b92915050565b5f602082840312156117a5576117a461155c565b5b5f6117b28482850161177c565b91505092915050565b6117c4816116ed565b82525050565b5f6020820190506117dd5f8301846117bb565b92915050565b5f5f5f606084860312156117fa576117f961155c565b5b5f61180786828701611714565b935050602061181886828701611714565b92505060406118298682870161177c565b9150509250925092565b5f602082840312156118485761184761155c565b5b5f61185584828501611714565b91505092915050565b5f819050919050565b5f61188161187c611877846116ce565b61185e565b6116ce565b9050919050565b5f61189282611867565b9050919050565b5f6118a382611888565b9050919050565b6118b381611899565b82525050565b5f6020820190506118cc5f8301846118aa565b92915050565b5f6118dc82611888565b9050919050565b6118ec816118d2565b82525050565b5f6020820190506119055f8301846118e3565b92915050565b5f8151905061191981611766565b92915050565b5f602082840312156119345761193361155c565b5b5f6119418482850161190b565b91505092915050565b5f60408201905061195d5f830185611651565b61196a6020830184611651565b9392505050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6119bb82611975565b810181811067ffffffffffffffff821117156119da576119d9611985565b5b80604052505050565b5f6119ec611553565b90506119f882826119b2565b919050565b5f67ffffffffffffffff821115611a1757611a16611985565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b5f7fffffffffffffffffffffffffffffffff0000000000000000000000000000000082169050919050565b611a6481611a30565b8114611a6e575f5ffd5b50565b5f81519050611a7f81611a5b565b92915050565b5f81519050611a93816116fe565b92915050565b5f60808284031215611aae57611aad611a2c565b5b611ab860806119e3565b90505f611ac784828501611a71565b5f830152506020611ada84828501611a85565b6020830152506040611aee8482850161190b565b6040830152506060611b028482850161190b565b60608301525092915050565b5f611b20611b1b846119fd565b6119e3565b90508083825260208201905060808402830185811115611b4357611b42611a28565b5b835b81811015611b6c5780611b588882611a99565b845260208401935050608081019050611b45565b5050509392505050565b5f82601f830112611b8a57611b89611971565b5b8151611b9a848260208601611b0e565b91505092915050565b5f60208284031215611bb857611bb761155c565b5b5f82015167ffffffffffffffff811115611bd557611bd4611560565b5b611be184828501611b76565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611c4e82611648565b9150611c5983611648565b9250828201905080821115611c7157611c70611c17565b5b92915050565b5f611c8182611648565b9150611c8c83611648565b9250828203905081811115611ca457611ca3611c17565b5b92915050565b5f611cb482611648565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ce657611ce5611c17565b5b600182019050919050565b5f606082019050611d045f830186611651565b611d116020830185611651565b611d1e60408301846115ef565b949350505050565b5f608082019050611d395f830187611651565b611d466020830186611651565b611d536040830185611651565b611d606060830184611651565b95945050505050565b5f819050919050565b5f611d8c611d87611d8284611d69565b61185e565b611648565b9050919050565b611d9c81611d72565b82525050565b5f604082019050611db55f830185611651565b611dc26020830184611d93565b9392505050565b611dd2816115e4565b8114611ddc575f5ffd5b50565b5f81519050611ded81611dc9565b92915050565b5f60208284031215611e0857611e0761155c565b5b5f611e1584828501611ddf565b91505092915050565b5f604082019050611e315f8301856117bb565b611e3e6020830184611620565b939250505056fea2646970667358221220f71c3ac32ba211820e16669ed267f0d4cc835b2f5183bbcd3d607a2ffe741f9964736f6c634300081e003300000000000000000000000046d6eba3aecd215a3e703cda963820d4520b45d6000000000000000000000000e8344867ab6387e17b7cae2de52c63bcf501bd98000000000000000000000000e8344867ab6387e17b7cae2de52c63bcf501bd98
Deployed Bytecode
0x608060405234801561000f575f5ffd5b506004361061012a575f3560e01c806391d14854116100ab578063e63ea4081161006f578063e63ea4081461030a578063ec2d3c0214610326578063f2fde38b14610330578063fbfa77cf1461034c578063fc0c546a1461036a5761012a565b806391d1485414610264578063a217fddf14610294578063ad7c6ed1146102b2578063c76bda86146102d0578063d547741f146102ee5761012a565b80633009a609116100f25780633009a609146101e657806336568abe146102045780634b5fb9c214610220578063715018a61461023c5780638da5cb5b146102465761012a565b806301ffc9a71461012e57806307bd02651461015e57806312065fe01461017c578063248a9ca31461019a5780632f2ff15d146101ca575b5f5ffd5b610148600480360381019061014391906115b9565b610388565b60405161015591906115fe565b60405180910390f35b610166610401565b604051610173919061162f565b60405180910390f35b610184610425565b6040516101919190611660565b60405180910390f35b6101b460048036038101906101af91906116a3565b6104c3565b6040516101c1919061162f565b60405180910390f35b6101e460048036038101906101df9190611728565b6104e0565b005b6101ee610502565b6040516101fb9190611660565b60405180910390f35b61021e60048036038101906102199190611728565b610508565b005b61023a60048036038101906102359190611790565b610583565b005b610244610a3d565b005b61024e610a50565b60405161025b91906117ca565b60405180910390f35b61027e60048036038101906102799190611728565b610a77565b60405161028b91906115fe565b60405180910390f35b61029c610adb565b6040516102a9919061162f565b60405180910390f35b6102ba610ae1565b6040516102c79190611660565b60405180910390f35b6102d8610ae7565b6040516102e59190611660565b60405180910390f35b61030860048036038101906103039190611728565b610aed565b005b610324600480360381019061031f91906117e3565b610b0f565b005b61032e610caf565b005b61034a60048036038101906103459190611833565b610eef565b005b610354610f73565b60405161036191906118b9565b60405180910390f35b610372610f97565b60405161037f91906118f2565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103fa57506103f982610fbb565b5b9050919050565b7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b5f7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161047f91906117ca565b602060405180830381865afa15801561049a573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104be919061191f565b905090565b5f60015f8381526020019081526020015f20600101549050919050565b6104e9826104c3565b6104f281611024565b6104fc8383611038565b50505050565b60025481565b610510611121565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610574576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61057e8282611128565b505050565b7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e636105ad81611024565b6105b5611212565b5f82036105ee576040517f8b4f6fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60025490505f7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161064e91906117ca565b602060405180830381865afa158015610669573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061068d919061191f565b90505f81036106c8576040517f669567ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f7f00000000000000000000000046d6eba3aecd215a3e703cda963820d4520b45d673ffffffffffffffffffffffffffffffffffffffff166345982a6684876040518363ffffffff1660e01b815260040161072492919061194a565b5f60405180830381865afa15801561073e573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906107669190611ba3565b90505f8151036107a2576040517f8b4f6fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f90505f8390505f5f90505b8351811080156107be57505f82115b156109d2575f8482815181106107d7576107d6611bea565b5b60200260200101516020015190505f8583815181106107f9576107f8611bea565b5b60200260200101516040015190505f86848151811061081b5761081a611bea565b5b602002602001015160600151905083896108359190611c44565b81146108855783896108479190611c44565b816040517f3efab60600000000000000000000000000000000000000000000000000000000815260040161087c92919061194a565b60405180910390fd5b5f600354836108949190611c77565b90505f868211156108a557866108a7565b815b905080886108b59190611c44565b975080876108c39190611c77565b96505f816003546108d49190611c44565b90505f8582101590508015610910575f6003819055506001856108f79190611c44565b600281905550878061090890611caa565b985050610918565b816003819055505b61096387847f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff1661123f9092919063ffffffff16565b8673ffffffffffffffffffffffffffffffffffffffff167f52da1513e99058a8135194d646824e865501f706eb0181ecd7a8e526d8a401118487846040516109ad93929190611cf1565b60405180910390a2806109c657505050505050506109d2565b505050505050506107af565b8260045f8282546109e39190611c44565b925050819055507f059092cb0d34e7f4af801acb970ca7f00bc4138c07427a5bb4b64394a736c8da8660025485600354604051610a239493929190611d26565b60405180910390a1505050505050610a39611292565b5050565b610a456112b6565b610a4e5f61133d565b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f60015f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f1b81565b60045481565b60035481565b610af6826104c3565b610aff81611024565b610b098383611128565b50505050565b610b176112b6565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b7c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610be1576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8103610c1a576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c4582828573ffffffffffffffffffffffffffffffffffffffff1661123f9092919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ff24ef89f38eadc1bde50701ad6e4d6d11a2dc24f7cf834a486991f388332850483604051610ca29190611660565b60405180910390a3505050565b610cb76112b6565b5f60025490505f7f00000000000000000000000046d6eba3aecd215a3e703cda963820d4520b45d673ffffffffffffffffffffffffffffffffffffffff166345982a668360016040518363ffffffff1660e01b8152600401610d1a929190611da2565b5f60405180830381865afa158015610d34573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610d5c9190611ba3565b90505f815103610d98576040517f8b4f6fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f815f81518110610dac57610dab611bea565b5b60200260200101516020015190507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff1663fe575a87826040518263ffffffff1660e01b8152600401610e1391906117ca565b602060405180830381865afa158015610e2e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e529190611df3565b610e9357806040517f36558c81000000000000000000000000000000000000000000000000000000008152600401610e8a91906117ca565b60405180910390fd5b600160025f828254610ea59190611c44565b925050819055505f6003819055507f1d6e89e7710bcd9a69582f2a65e41027d0d6e46da22ad9255d6f2a2a9655b60183604051610ee29190611660565b60405180910390a1505050565b610ef76112b6565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610f67575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610f5e91906117ca565b60405180910390fd5b610f708161133d565b50565b7f00000000000000000000000046d6eba3aecd215a3e703cda963820d4520b45d681565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61103581611030611121565b6113fe565b50565b5f6110438383610a77565b611117576001805f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506110b4611121565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001905061111b565b5f90505b92915050565b5f33905090565b5f6111338383610a77565b15611208575f60015f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506111a5611121565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a46001905061120c565b5f90505b92915050565b61121a61144f565b61123d600161122f61122a611490565b6114b9565b6114c290919063ffffffff16565b565b61124c83838360016114c9565b61128d57826040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161128491906117ca565b60405180910390fd5b505050565b6112b45f6112a66112a1611490565b6114b9565b6114c290919063ffffffff16565b565b6112be611121565b73ffffffffffffffffffffffffffffffffffffffff166112dc610a50565b73ffffffffffffffffffffffffffffffffffffffff161461133b576112ff611121565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161133291906117ca565b60405180910390fd5b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6114088282610a77565b61144b5780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401611442929190611e1e565b60405180910390fd5b5050565b61145761152b565b1561148e576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005f1b905090565b5f819050919050565b80825d5050565b5f5f63a9059cbb60e01b9050604051815f525f1960601c86166004528460245260205f60445f5f8b5af1925060015f5114831661151d578383151615611511573d5f823e3d81fd5b5f873b113d1516831692505b806040525050949350505050565b5f61154461153f61153a611490565b6114b9565b611549565b905090565b5f815c9050919050565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61159881611564565b81146115a2575f5ffd5b50565b5f813590506115b38161158f565b92915050565b5f602082840312156115ce576115cd61155c565b5b5f6115db848285016115a5565b91505092915050565b5f8115159050919050565b6115f8816115e4565b82525050565b5f6020820190506116115f8301846115ef565b92915050565b5f819050919050565b61162981611617565b82525050565b5f6020820190506116425f830184611620565b92915050565b5f819050919050565b61165a81611648565b82525050565b5f6020820190506116735f830184611651565b92915050565b61168281611617565b811461168c575f5ffd5b50565b5f8135905061169d81611679565b92915050565b5f602082840312156116b8576116b761155c565b5b5f6116c58482850161168f565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6116f7826116ce565b9050919050565b611707816116ed565b8114611711575f5ffd5b50565b5f81359050611722816116fe565b92915050565b5f5f6040838503121561173e5761173d61155c565b5b5f61174b8582860161168f565b925050602061175c85828601611714565b9150509250929050565b61176f81611648565b8114611779575f5ffd5b50565b5f8135905061178a81611766565b92915050565b5f602082840312156117a5576117a461155c565b5b5f6117b28482850161177c565b91505092915050565b6117c4816116ed565b82525050565b5f6020820190506117dd5f8301846117bb565b92915050565b5f5f5f606084860312156117fa576117f961155c565b5b5f61180786828701611714565b935050602061181886828701611714565b92505060406118298682870161177c565b9150509250925092565b5f602082840312156118485761184761155c565b5b5f61185584828501611714565b91505092915050565b5f819050919050565b5f61188161187c611877846116ce565b61185e565b6116ce565b9050919050565b5f61189282611867565b9050919050565b5f6118a382611888565b9050919050565b6118b381611899565b82525050565b5f6020820190506118cc5f8301846118aa565b92915050565b5f6118dc82611888565b9050919050565b6118ec816118d2565b82525050565b5f6020820190506119055f8301846118e3565b92915050565b5f8151905061191981611766565b92915050565b5f602082840312156119345761193361155c565b5b5f6119418482850161190b565b91505092915050565b5f60408201905061195d5f830185611651565b61196a6020830184611651565b9392505050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6119bb82611975565b810181811067ffffffffffffffff821117156119da576119d9611985565b5b80604052505050565b5f6119ec611553565b90506119f882826119b2565b919050565b5f67ffffffffffffffff821115611a1757611a16611985565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b5f7fffffffffffffffffffffffffffffffff0000000000000000000000000000000082169050919050565b611a6481611a30565b8114611a6e575f5ffd5b50565b5f81519050611a7f81611a5b565b92915050565b5f81519050611a93816116fe565b92915050565b5f60808284031215611aae57611aad611a2c565b5b611ab860806119e3565b90505f611ac784828501611a71565b5f830152506020611ada84828501611a85565b6020830152506040611aee8482850161190b565b6040830152506060611b028482850161190b565b60608301525092915050565b5f611b20611b1b846119fd565b6119e3565b90508083825260208201905060808402830185811115611b4357611b42611a28565b5b835b81811015611b6c5780611b588882611a99565b845260208401935050608081019050611b45565b5050509392505050565b5f82601f830112611b8a57611b89611971565b5b8151611b9a848260208601611b0e565b91505092915050565b5f60208284031215611bb857611bb761155c565b5b5f82015167ffffffffffffffff811115611bd557611bd4611560565b5b611be184828501611b76565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611c4e82611648565b9150611c5983611648565b9250828201905080821115611c7157611c70611c17565b5b92915050565b5f611c8182611648565b9150611c8c83611648565b9250828203905081811115611ca457611ca3611c17565b5b92915050565b5f611cb482611648565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ce657611ce5611c17565b5b600182019050919050565b5f606082019050611d045f830186611651565b611d116020830185611651565b611d1e60408301846115ef565b949350505050565b5f608082019050611d395f830187611651565b611d466020830186611651565b611d536040830185611651565b611d606060830184611651565b95945050505050565b5f819050919050565b5f611d8c611d87611d8284611d69565b61185e565b611648565b9050919050565b611d9c81611d72565b82525050565b5f604082019050611db55f830185611651565b611dc26020830184611d93565b9392505050565b611dd2816115e4565b8114611ddc575f5ffd5b50565b5f81519050611ded81611dc9565b92915050565b5f60208284031215611e0857611e0761155c565b5b5f611e1584828501611ddf565b91505092915050565b5f604082019050611e315f8301856117bb565b611e3e6020830184611620565b939250505056fea2646970667358221220f71c3ac32ba211820e16669ed267f0d4cc835b2f5183bbcd3d607a2ffe741f9964736f6c634300081e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000046d6eba3aecd215a3e703cda963820d4520b45d6000000000000000000000000e8344867ab6387e17b7cae2de52c63bcf501bd98000000000000000000000000e8344867ab6387e17b7cae2de52c63bcf501bd98
-----Decoded View---------------
Arg [0] : _vault (address): 0x46D6Eba3AECD215a3e703cdA963820d4520b45D6
Arg [1] : _owner (address): 0xe8344867AB6387e17b7cAE2dE52C63BCf501BD98
Arg [2] : _executor (address): 0xe8344867AB6387e17b7cAE2dE52C63BCf501BD98
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000046d6eba3aecd215a3e703cda963820d4520b45d6
Arg [1] : 000000000000000000000000e8344867ab6387e17b7cae2de52c63bcf501bd98
Arg [2] : 000000000000000000000000e8344867ab6387e17b7cae2de52c63bcf501bd98
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $0.999803 | 80.2385 | $80.22 |
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.