Address Contract Verified
Address
0x4461C5a2dDCaDC2E93f5cf8dacbCc2621497870C
Balance
0 ETH
Nonce
1
Code Size
6284 bytes
Creator
0xD0f2390b...bF13 at tx 0x58bcde90...1a187a
Indexed Transactions
0
Contract Bytecode
6284 bytes
0x608060405234801561001057600080fd5b50600436106100be5760003560e01c80638da5cb5b11610076578063abbf68d81161005b578063abbf68d8146101b3578063d8a270b6146101c6578063f2fde38b146101d957600080fd5b80638da5cb5b1461015b5780639f5389d6146101a057600080fd5b8063579d90bc116100a7578063579d90bc1461012257806357c5e2481461013557806385ab1b1b1461014857600080fd5b80633c4acba0146100c357806354fd4d50146100eb575b600080fd5b6100d66100d1366004611219565b6101ee565b60405190151581526020015b60405180910390f35b6000546101109074010000000000000000000000000000000000000000900460ff1681565b60405160ff90911681526020016100e2565b6100d661013036600461127e565b610402565b6100d661014336600461132f565b61051c565b6100d661015636600461139c565b61067b565b60005461017b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e2565b6100d66101ae366004611436565b61082f565b6100d66101c136600461149f565b6108fd565b6100d66101d4366004611517565b610a10565b6101ec6101e736600461155e565b610bba565b005b6000805473ffffffffffffffffffffffffffffffffffffffff163314610275576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b84836000805b828110156103995760006102a7858a8a8581811061029b5761029b611580565b90506101000201610cab565b905060008989848181106102bd576102bd611580565b9050610100020160200160208101906102d6919061155e565b90508160010361038f576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152600091908816906370a0823190602401602060405180830381865afa158015610350573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037491906115af565b9050801561038d5761038887838b84610f6e565b850194505b505b505060010161027b565b5073ffffffffffffffffffffffffffffffffffffffff881660017fe3ee7eccea85e8abb08e083b7904bc1e6368e6b58ec3b0083c552b90c86aad07836103df81876115c8565b6040805192835260208301919091520160405180910390a3149695505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff163314610484576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015260640161026c565b83826000805b828110156104b4576104a88488888481811061029b5761029b611580565b9091019060010161048a565b5073ffffffffffffffffffffffffffffffffffffffff871660007fe3ee7eccea85e8abb08e083b7904bc1e6368e6b58ec3b0083c552b90c86aad07836104fa81876115c8565b6040805192835260208301919091520160405180910390a31495945050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff16331461059e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015260640161026c565b85836000805b828110156106115760006105b8858b610cab565b90508060010361060857610603856105d660408d0160208e0161155e565b8b8b868181106105e8576105e8611580565b90506020020160208101906105fd919061155e565b8a610f6e565b830192505b506001016105a4565b5073ffffffffffffffffffffffffffffffffffffffff891660017fe3ee7eccea85e8abb08e083b7904bc1e6368e6b58ec3b0083c552b90c86aad078361065781876115c8565b6040805192835260208301919091520160405180910390a314979650505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff1633146106fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015260640161026c565b83828114610737576040517f543bf3c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b876000805b838110156107c1576000610750848c610cab565b9050806001036107b8576107b38461076e60408e0160208f0161155e565b8c8c8681811061078057610780611580565b9050602002016020810190610795919061155e565b8b8b878181106107a7576107a7611580565b90506020020135610f6e565b830192505b5060010161073c565b5073ffffffffffffffffffffffffffffffffffffffff8a1660017fe3ee7eccea85e8abb08e083b7904bc1e6368e6b58ec3b0083c552b90c86aad078361080781886115c8565b6040805192835260208301919091520160405180910390a39091149150509695505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff1633146108b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015260640161026c565b85836000805b82811015610611576108f1848a8a8a858181106108d6576108d6611580565b90506020020160208101906108eb919061155e565b89610f6e565b909101906001016108b7565b6000805473ffffffffffffffffffffffffffffffffffffffff16331461097f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015260640161026c565b838281146109b9576040517f543bf3c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b876000805b838110156107c157610a04838b8b8b858181106109dd576109dd611580565b90506020020160208101906109f2919061155e565b8a8a868181106107a7576107a7611580565b909101906001016109be565b6000805473ffffffffffffffffffffffffffffffffffffffff163314610a92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015260640161026c565b84836000805b828110156103995760008473ffffffffffffffffffffffffffffffffffffffff166370a082318a8a85818110610ad057610ad0611580565b9050602002016020810190610ae5919061155e565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401602060405180830381865afa158015610b4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7291906115af565b90508015610bb157610bac858a8a85818110610b9057610b90611580565b9050602002016020810190610ba5919061155e565b8984610f6e565b830192505b50600101610a98565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015260640161026c565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b6000610cba6020830183611613565b15610cc757506001610f68565b600073ffffffffffffffffffffffffffffffffffffffff841663d505accf610cf5604086016020870161155e565b610d05606087016040880161155e565b60608701356080880135610d1f60c08a0160a08b01611630565b60405160e087811b7fffffffff0000000000000000000000000000000000000000000000000000000016825273ffffffffffffffffffffffffffffffffffffffff96871660048301529490951660248601526044850192909252606484015260ff16608483015260c087013560a483015286013560c482015260e401600060405180830381600087803b158015610db557600080fd5b505af1925050508015610dc6575060015b610f6157610dd2611653565b806308c379a003610e5b5750610de66116e1565b80610df15750610ed5565b610e01604085016020860161155e565b73ffffffffffffffffffffffffffffffffffffffff90811690861660007fe2fb6362e3465fcbf170f1d31a8da553e10702bb2c7858d97b006cc6ede0a66484604051610e4d9190611806565b60405180910390a450610f65565b634e487b7103610ed557610e6d611819565b90610e785750610ed5565b610e88604085016020860161155e565b73ffffffffffffffffffffffffffffffffffffffff90811690861660006040518481527f19fee171589f1bedfaab8b25fc1e901721977334b70c07f92a02bd21465f150c90602001610e4d565b3d808015610eff576040519150601f19603f3d011682016040523d82523d6000602084013e610f04565b606091505b50610f15604085016020860161155e565b73ffffffffffffffffffffffffffffffffffffffff90811690861660007fe440cc235d8991a03cf744416ab22d331204c73ec68a851691e045f81f73934a84604051610e4d9190611806565b5060015b90505b92915050565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015283811660248301526044820183905260009182918716906323b872dd906064016020604051808303816000875af192505050801561102a575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261102791810190611839565b60015b61119557611036611653565b806308c379a0036110af575061104a6116e1565b806110555750611119565b73ffffffffffffffffffffffffffffffffffffffff80871690881660017fe2fb6362e3465fcbf170f1d31a8da553e10702bb2c7858d97b006cc6ede0a664846040516110a19190611806565b60405180910390a45061119b565b634e487b7103611119576110c1611819565b906110cc5750611119565b73ffffffffffffffffffffffffffffffffffffffff80871690881660016040518481527f19fee171589f1bedfaab8b25fc1e901721977334b70c07f92a02bd21465f150c906020016110a1565b3d808015611143576040519150601f19603f3d011682016040523d82523d6000602084013e611148565b606091505b5073ffffffffffffffffffffffffffffffffffffffff80871690881660017fe440cc235d8991a03cf744416ab22d331204c73ec68a851691e045f81f73934a846040516110a19190611806565b50600190505b95945050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146111c857600080fd5b919050565b60008083601f8401126111df57600080fd5b50813567ffffffffffffffff8111156111f757600080fd5b6020830191508360208260081b850101111561121257600080fd5b9250929050565b6000806000806060858703121561122f57600080fd5b611238856111a4565b9350602085013567ffffffffffffffff81111561125457600080fd5b611260878288016111cd565b90945092506112739050604086016111a4565b905092959194509250565b60008060006040848603121561129357600080fd5b61129c846111a4565b9250602084013567ffffffffffffffff8111156112b857600080fd5b6112c4868287016111cd565b9497909650939450505050565b600061010082840312156112e457600080fd5b50919050565b60008083601f8401126112fc57600080fd5b50813567ffffffffffffffff81111561131457600080fd5b6020830191508360208260051b850101111561121257600080fd5b6000806000806000610160868803121561134857600080fd5b611351866111a4565b945061136087602088016112d1565b935061012086013567ffffffffffffffff81111561137d57600080fd5b611389888289016112ea565b9699959850966101400135949350505050565b60008060008060008061016087890312156113b657600080fd5b6113bf876111a4565b95506113ce88602089016112d1565b945061012087013567ffffffffffffffff8111156113eb57600080fd5b6113f789828a016112ea565b90955093505061014087013567ffffffffffffffff81111561141857600080fd5b61142489828a016112ea565b979a9699509497509295939492505050565b60008060008060006080868803121561144e57600080fd5b611457866111a4565b9450611465602087016111a4565b9350604086013567ffffffffffffffff81111561148157600080fd5b61148d888289016112ea565b96999598509660600135949350505050565b600080600080600080608087890312156114b857600080fd5b6114c1876111a4565b95506114cf602088016111a4565b9450604087013567ffffffffffffffff8111156114eb57600080fd5b6114f789828a016112ea565b909550935050606087013567ffffffffffffffff81111561141857600080fd5b6000806000806060858703121561152d57600080fd5b611536856111a4565b9350602085013567ffffffffffffffff81111561155257600080fd5b611260878288016112ea565b60006020828403121561157057600080fd5b611579826111a4565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156115c157600080fd5b5051919050565b81810381811115610f68577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b801515811461161057600080fd5b50565b60006020828403121561162557600080fd5b8135610f6581611602565b60006020828403121561164257600080fd5b813560ff81168114610f6557600080fd5b600060033d111561166c5760046000803e5060005160e01c5b90565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116810181811067ffffffffffffffff821117156116da577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040525050565b600060443d10156116ef5790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3d016004823e80513d602482011167ffffffffffffffff8211171561173757505090565b808201805167ffffffffffffffff811115611753575050505090565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3d850101602082840101111561178b575050505090565b61179a6020828501018561166f565b509392505050565b6000815180845260005b818110156117c8576020818501810151868301820152016117ac565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061157960208301846117a2565b60008060233d1115611835576020600460003e50506000516001905b9091565b60006020828403121561184b57600080fd5b8151610f658161160256fea2646970667358221220a3214b4a6107ebb9187c9cd0bd781978affdcc373588197d0f6259d6edcfd22564736f6c634300081b0033
Verified Source Code Full Match
Compiler: v0.8.27+commit.40a35a09
EVM: paris
Optimization: Yes (10000 runs)
AlloyBatch.sol 233 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;
import {Owned} from "solmate-6.8.0/src/auth/Owned.sol";
import {IERC20Permit} from "lib/shared/IERC20Permit.sol";
import {IBatch} from "./IBatch.sol";
import {Types} from "./Types.sol";
contract AlloyBatch is IBatch, Owned(msg.sender) {
uint8 public version = 1;
enum BatchType {
Permit,
TransferFrom
}
/// @return boolean derived from comparing the number of permits given and the number of permits succeeded
function batchPermit(address token, Types.Permit[] calldata permits) external onlyOwner returns (bool) {
IERC20Permit ERC20 = IERC20Permit(token);
uint256 len = permits.length;
uint256 batched = 0;
// NOTE sol compiler as of ..22 no longer needs the unchecked i increments
for (uint256 i = 0; i < len; ++i) {
unchecked {
batched += doPermit(ERC20, permits[i]);
}
}
emit Batched(uint256(BatchType.Permit), token, batched, (len - batched));
return batched == len;
}
function doPermit(IERC20Permit ERC20, Types.Permit calldata permit) internal returns (uint256) {
// base case is that the permit has already been done
if (permit.done) return 1;
uint256 res = 0;
try ERC20.permit(permit.owner, permit.spender, permit.value, permit.deadline, permit.v, permit.r, permit.s) {
res = 1;
} catch Panic(uint256 code) {
// catches any illegal operations and assert failures
emit BatchFail(uint256(BatchType.Permit), address(ERC20), permit.owner, code);
} catch Error(string memory reason) {
// catches any revert(string) and require(.., '')
emit BatchFail(uint256(BatchType.Permit), address(ERC20), permit.owner, reason);
} catch (bytes memory data) {
// catch all for anything not described above
emit BatchFail(uint256(BatchType.Permit), address(ERC20), permit.owner, data);
}
return res;
}
// ****** from many to one *****************************************************************************************
function batchTransferFrom(address token, address[] calldata from, address to) external onlyOwner returns (bool) {
IERC20Permit ERC20 = IERC20Permit(token);
uint256 len = from.length;
uint256 batched = 0;
for (uint256 i = 0; i < len; ++i) {
uint256 bal = ERC20.balanceOf(from[i]);
// TODO we could check the allowance here, but likely not necessary as we will have mass permitted MAX_UINT
if (bal > 0) {
unchecked {
batched += doTransferFrom(ERC20, from[i], to, bal);
}
}
}
emit Batched(uint256(BatchType.TransferFrom), token, batched, (len - batched));
return batched == len;
}
/// @dev there is a case here where a permit succeeds and a transferFrom fails. this is acceptable
/// as the token itself will emit Approval if verification is needed. the 'failed' count here is
/// representative of failed transfers. also a found 0 balance is a noop
function batchTransferFrom(address token, Types.Permit[] calldata permits, address to)
external
onlyOwner
returns (bool)
{
IERC20Permit ERC20 = IERC20Permit(token);
uint256 len = permits.length;
uint256 batched = 0;
for (uint256 i = 0; i < len; ++i) {
// first, the permit must adjust the allowance, if this fails do not proceed this iteration
uint256 permitted = doPermit(ERC20, permits[i]);
// then, we can transfer
address from = permits[i].owner;
if (permitted == 1) {
uint256 bal = ERC20.balanceOf(from);
if (bal > 0) {
unchecked {
batched += doTransferFrom(ERC20, from, to, bal);
}
}
}
}
emit Batched(uint256(BatchType.TransferFrom), token, batched, (len - batched));
return batched == len;
}
// ****** from one to many *****************************************************************************************
function batchTransferFrom(address token, address from, address[] calldata to, uint256 amount)
external
onlyOwner
returns (bool)
{
IERC20Permit ERC20 = IERC20Permit(token);
uint256 len = to.length;
uint256 batched = 0;
for (uint256 i = 0; i < len; ++i) {
unchecked {
batched += doTransferFrom(ERC20, from, to[i], amount);
}
}
emit Batched(uint256(BatchType.TransferFrom), token, batched, (len - batched));
return batched == len;
}
function batchTransferFrom(address token, Types.Permit calldata permit, address[] calldata to, uint256 amount)
external
onlyOwner
returns (bool)
{
IERC20Permit ERC20 = IERC20Permit(token);
uint256 len = to.length;
uint256 batched = 0;
for (uint256 i = 0; i < len; ++i) {
uint256 permitted = doPermit(ERC20, permit);
if (permitted == 1) {
unchecked {
batched += doTransferFrom(ERC20, permit.owner, to[i], amount);
}
}
}
emit Batched(uint256(BatchType.TransferFrom), token, batched, (len - batched));
return batched == len;
}
/// @dev invariant that the array args are of equivalent length
function batchTransferFrom(address token, address from, address[] calldata to, uint256[] calldata amounts)
external
onlyOwner
returns (bool)
{
uint256 len = to.length;
if (len != amounts.length) revert arrayLengthMismatch();
IERC20Permit ERC20 = IERC20Permit(token);
uint256 batched = 0;
for (uint256 i = 0; i < len; ++i) {
unchecked {
batched += doTransferFrom(ERC20, from, to[i], amounts[i]);
}
}
emit Batched(uint256(BatchType.TransferFrom), token, batched, (len - batched));
return batched == len;
}
function batchTransferFrom(
address token,
Types.Permit calldata permit,
address[] calldata to,
uint256[] calldata amounts
) external onlyOwner returns (bool) {
uint256 len = to.length;
if (len != amounts.length) revert arrayLengthMismatch();
IERC20Permit ERC20 = IERC20Permit(token);
uint256 batched = 0;
for (uint256 i = 0; i < len; ++i) {
uint256 permitted = doPermit(ERC20, permit);
if (permitted == 1) {
unchecked {
batched += doTransferFrom(ERC20, permit.owner, to[i], amounts[i]);
}
}
}
emit Batched(uint256(BatchType.TransferFrom), token, batched, (len - batched));
return batched == len;
}
function doTransferFrom(IERC20Permit ERC20, address from, address to, uint256 amount) internal returns (uint256) {
uint256 res = 0;
try ERC20.transferFrom(from, to, amount) {
res = 1;
} catch Panic(uint256 code) {
// catches any illegal operations and assert failures
emit BatchFail(uint256(BatchType.TransferFrom), address(ERC20), from, code);
} catch Error(string memory reason) {
// catches any revert(string) and require(.., '')
emit BatchFail(uint256(BatchType.TransferFrom), address(ERC20), from, reason);
} catch (bytes memory data) {
// catch all for anything not described above
emit BatchFail(uint256(BatchType.TransferFrom), address(ERC20), from, data);
}
return res;
}
}
Owned.sol 44 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event OwnershipTransferred(address indexed user, address indexed newOwner);
/*//////////////////////////////////////////////////////////////
OWNERSHIP STORAGE
//////////////////////////////////////////////////////////////*/
address public owner;
modifier onlyOwner() virtual {
require(msg.sender == owner, "UNAUTHORIZED");
_;
}
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address _owner) {
owner = _owner;
emit OwnershipTransferred(address(0), _owner);
}
/*//////////////////////////////////////////////////////////////
OWNERSHIP LOGIC
//////////////////////////////////////////////////////////////*/
function transferOwnership(address newOwner) public virtual onlyOwner {
owner = newOwner;
emit OwnershipTransferred(msg.sender, newOwner);
}
}
IERC20Permit.sol 95 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.22;
/**
* @dev the interface has been combined / truncated to only our needs
*/
/**
* @dev Interface of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[ERC-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC-20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @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 `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);
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
}
IBatch.sol 74 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;
import {Types} from "./Types.sol";
interface IBatch {
/**
* @dev Emitted at the conclusion of a batch operation.
* args:
* kind - Type of batch
* token - address of the token called
* succeeded - the number of successful calls
* failed - the number which failed
*/
event Batched(uint256 indexed kind, address indexed token, uint256 succeeded, uint256 failed);
/**
* @dev Emmitted for each fail that occurs in a batching loop.
* args:
* kind - Type of batch
* token - address of the token called
* user - address of the user whose tx failed
* code / reason / data - returned data depending on error type
*/
event BatchFail(uint256 indexed kind, address indexed token, address indexed user, uint256 code);
event BatchFail(uint256 indexed kind, address indexed token, address indexed user, string reason);
event BatchFail(uint256 indexed kind, address indexed token, address indexed user, bytes data);
/// @notice given a target permit token and a list of permit payloads, execute the permit call for each
function batchPermit(address token, Types.Permit[] calldata permits) external returns (bool);
// ****** from many to one *******************************************************************************************
/// @notice given a target token and a list of senders, transfer their entire balance to a given receiver
/// @dev a permit is assumed to have already been performed in this case
function batchTransferFrom(address token, address[] calldata from, address to) external returns (bool);
/// @notice given a target token, an array of permits and a recipient, perform both the permit and transfer
/// @dev the permits will need to allow address(this) for the an amount >= the owner's balance. also, from
/// is not required as permit.owner will be used
function batchTransferFrom(address token, Types.Permit[] calldata permits, address to) external returns (bool);
// ****** from one to many ******************************************************************************************
/// @notice given a target token, a sender, a list of receivers and an amount, transfer to each
/// @dev a permit is assumed to have already been performed in this case
function batchTransferFrom(address token, address from, address[] calldata to, uint256 amount)
external
returns (bool);
/// @notice same as the above, however include a permit authorizing address(this)
/// @dev the permit is expected to allow (at a minimum) the sum of all amounts sent. also,
/// from is not passed here, permit.owner will be used
function batchTransferFrom(address token, Types.Permit calldata permit, address[] calldata to, uint256 amount)
external
returns (bool);
/// @notice given a target token, a sender, a list of recievers and a list of amounts, transfer to each
function batchTransferFrom(address token, address from, address[] calldata to, uint256[] calldata amounts)
external
returns (bool);
/// @notice same as above, however include a permit authorizing address(this)
/// @dev the permit is expected to allow (at a minimum) the sum of all amounts sent. also,
/// from is not passed here, permit.owner will be used
function batchTransferFrom(
address token,
Types.Permit calldata permit,
address[] calldata to,
uint256[] calldata amounts
) external returns (bool);
error arrayLengthMismatch();
}
Types.sol 18 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;
/// @dev the `done` boolean is a flag to indicate that a permit call for this owner has aleady happened.
/// we do this to allow an API to pass 'mixed' arrays of permitted/nonpermitted users - preventing them from
/// needing to make multiple calls. Note that in the `done` case, only `owner` is needed.
library Types {
struct Permit {
bool done;
address owner;
address spender;
uint256 value;
uint256 deadline;
uint8 v;
bytes32 r;
bytes32 s;
}
}
Read Contract
owner 0x8da5cb5b → address
version 0x54fd4d50 → uint8
Write Contract 8 functions
These functions modify contract state and require a wallet transaction to execute.
batchPermit 0x0ad2dccf
address token
tuple[] permits
returns: bool
batchTransferFrom 0xb8f0e72a
address token
tuple[] permits
address to
returns: bool
batchTransferFrom 0xe6bb37c6
address token
tuple permit
address[] to
uint256 amount
returns: bool
batchTransferFrom 0xc8176dc4
address token
tuple permit
address[] to
uint256[] amounts
returns: bool
batchTransferFrom 0x9f5389d6
address token
address from
address[] to
uint256 amount
returns: bool
batchTransferFrom 0xabbf68d8
address token
address from
address[] to
uint256[] amounts
returns: bool
batchTransferFrom 0xd8a270b6
address token
address[] from
address to
returns: bool
transferOwnership 0xf2fde38b
address newOwner
Recent Transactions
No transactions found for this address