文件 1 的 16:ActionModule.sol
pragma solidity ^0.8.0;
pragma abicoder v2;
import "@openzeppelin/contracts/utils/math/Math.sol";
import "../../utils/Timers.sol";
import "../ModuleBase.sol";
contract ActionModule is IModule, ModuleBase, Timers
{
string public constant override name = type(ActionModule).name;
bytes32 public constant ACTION_DURATION = 0x05f91198c37cc2578c2915e1614db3bf5c90e3387bd106bdfbb0da82514418dd;
bytes32 public constant ACTION_AUTH_RATIO = 0x3c3813978ff64b4dbcec0d1ea3c72ec1393a708e0a785f2797bac1f61c3d7e09;
event ActionScheduled(ShardedWallet indexed wallet, bytes32 indexed uid, bytes32 indexed id, uint256 i, address to, uint256 value, bytes data);
event ActionExecuted(ShardedWallet indexed wallet, bytes32 indexed uid, bytes32 indexed id, uint256 i, address to, uint256 value, bytes data);
event ActionCancelled(ShardedWallet indexed wallet, bytes32 indexed uid, bytes32 indexed id);
modifier actionAuthorized(ShardedWallet wallet, address user)
{
require(wallet.balanceOf(user) >= Math.max(
wallet.totalSupply() * wallet.governance().getConfig(address(wallet), ACTION_AUTH_RATIO) / 10**18,
1
));
_;
}
constructor(address walletTemplate) ModuleBase(walletTemplate) {}
function schedule(ShardedWallet wallet, address[] memory to, uint256[] memory value, bytes[] memory data)
public actionAuthorized(wallet, msg.sender) returns (bytes32)
{
require(to.length == value.length);
require(to.length == data.length);
bytes32 id = keccak256(abi.encode(to, value, data));
bytes32 uid = keccak256(abi.encode(wallet, id));
Timers._startTimer(uid, wallet.governance().getConfig(address(wallet), ACTION_DURATION));
for (uint256 i = 0; i < to.length; ++i) {
emit ActionScheduled(wallet, uid, id, i, to[i], value[i], data[i]);
}
return id;
}
function execute(ShardedWallet wallet, address[] memory to, uint256[] memory value, bytes[] memory data)
public actionAuthorized(wallet, msg.sender) returns (bool)
{
require(wallet.owner() == address(0));
require(to.length == value.length);
require(to.length == data.length);
bytes32 id = keccak256(abi.encode(to, value, data));
bytes32 uid = keccak256(abi.encode(wallet, id));
Timers._resetTimer(uid);
for (uint256 i = 0; i < to.length; ++i) {
wallet.moduleExecute(to[i], value[i], data[i]);
emit ActionExecuted(wallet, uid, id, i, to[i], value[i], data[i]);
}
return true;
}
function cancel(ShardedWallet wallet, bytes32 id)
public actionAuthorized(wallet, msg.sender) returns (bool)
{
bytes32 uid = keccak256(abi.encode(wallet, id));
Timers._stopTimer(uid);
emit ActionCancelled(wallet, uid, id);
return true;
}
}
文件 2 的 16:Address.sol
pragma solidity ^0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 3 的 16:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this;
return msg.data;
}
}
文件 4 的 16:ERC1363.sol
pragma solidity ^0.8.0;
import "./ERC20.sol";
import "../interface/IERC1363.sol";
import "../interface/IERC1363Receiver.sol";
import "../interface/IERC1363Spender.sol";
abstract contract ERC1363Transfer is ERC20, IERC1363Transfer {
function transferAndCall(address to, uint256 value) public override returns (bool) {
return transferAndCall(to, value, bytes(""));
}
function transferAndCall(address to, uint256 value, bytes memory data) public override returns (bool) {
require(transfer(to, value));
try IERC1363Receiver(to).onTransferReceived(_msgSender(), _msgSender(), value, data) returns (bytes4 selector) {
require(selector == IERC1363Receiver(to).onTransferReceived.selector, "ERC1363: onTransferReceived invalid result");
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1363: onTransferReceived reverted without reason");
}
return true;
}
function transferFromAndCall(address from, address to, uint256 value) public override returns (bool) {
return transferFromAndCall(from, to, value, bytes(""));
}
function transferFromAndCall(address from, address to, uint256 value, bytes memory data) public override returns (bool) {
require(transferFrom(from, to, value));
try IERC1363Receiver(to).onTransferReceived(_msgSender(), from, value, data) returns (bytes4 selector) {
require(selector == IERC1363Receiver(to).onTransferReceived.selector, "ERC1363: onTransferReceived invalid result");
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1363: onTransferReceived reverted without reason");
}
return true;
}
}
abstract contract ERC1363Approve is ERC20, IERC1363Approve {
function approveAndCall(address spender, uint256 value) public override returns (bool) {
return approveAndCall(spender, value, bytes(""));
}
function approveAndCall(address spender, uint256 value, bytes memory data) public override returns (bool) {
require(approve(spender, value));
try IERC1363Spender(spender).onApprovalReceived(_msgSender(), value, data) returns (bytes4 selector) {
require(selector == IERC1363Spender(spender).onApprovalReceived.selector, "ERC1363: onApprovalReceived invalid result");
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1363: onApprovalReceived reverted without reason");
}
return true;
}
}
abstract contract ERC1363 is ERC1363Transfer, ERC1363Approve {}
文件 5 的 16:ERC20.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract ERC20 is Context, IERC20 {
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
function _initialize(string memory name_, string memory symbol_) internal virtual {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual returns (string memory) {
return _name;
}
function symbol() public view virtual returns (string memory) {
return _symbol;
}
function decimals() public view virtual returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
_approve(sender, _msgSender(), currentAllowance - amount);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
uint256 currentAllowance = _allowances[_msgSender()][spender];
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
_approve(_msgSender(), spender, currentAllowance - subtractedValue);
return true;
}
function burn(uint256 amount) public virtual {
_burn(_msgSender(), amount);
}
function burnFrom(address account, uint256 amount) public virtual {
uint256 currentAllowance = allowance(account, _msgSender());
require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
_approve(account, _msgSender(), currentAllowance - amount);
_burn(account, amount);
}
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
_balances[sender] = senderBalance - amount;
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
_balances[account] = accountBalance - amount;
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
}
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}
文件 6 的 16:IERC1363.sol
pragma solidity ^0.8.0;
interface IERC1363Transfer {
function transferAndCall(address to, uint256 value) external returns (bool);
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
}
interface IERC1363Approve {
function approveAndCall(address spender, uint256 value) external returns (bool);
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}
interface IERC1363 is IERC1363Transfer, IERC1363Approve {
}
文件 7 的 16:IERC1363Receiver.sol
pragma solidity ^0.8.0;
interface IERC1363Receiver {
function onTransferReceived(address operator, address from, uint256 value, bytes calldata data) external returns (bytes4);
}
文件 8 的 16:IERC1363Spender.sol
pragma solidity ^0.8.0;
interface IERC1363Spender {
function onApprovalReceived(address owner, uint256 value, bytes calldata data) external returns (bytes4);
}
文件 9 的 16:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 10 的 16:IGovernance.sol
pragma solidity ^0.8.0;
interface IGovernance
{
function isModule(address, address) external view returns (bool);
function isAuthorized(address, address) external view returns (bool);
function getModule(address, bytes4) external view returns (address);
function getConfig(address, bytes32) external view returns (uint256);
function getNiftexWallet() external view returns (address);
}
文件 11 的 16:IModule.sol
pragma solidity ^0.8.0;
interface IModule
{
function name() external view returns (string memory);
}
文件 12 的 16:Math.sol
pragma solidity ^0.8.0;
library Math {
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
}
}
文件 13 的 16:ModuleBase.sol
pragma solidity ^0.8.0;
import "../wallet/ShardedWallet.sol";
import "./IModule.sol";
abstract contract ModuleBase is IModule
{
address immutable public walletTemplate;
constructor(address walletTemplate_)
{
walletTemplate = walletTemplate_;
}
modifier onlyShardedWallet(ShardedWallet wallet)
{
require(isClone(walletTemplate, address(wallet)));
_;
}
modifier onlyAuthorized(ShardedWallet wallet, address user)
{
require(wallet.governance().isAuthorized(address(wallet), user));
_;
}
modifier onlyOwner(ShardedWallet wallet, address user)
{
require(wallet.owner() == user);
_;
}
function isClone(address target, address query)
internal view returns (bool result)
{
bytes20 targetBytes = bytes20(target);
assembly {
let clone := mload(0x40)
mstore(clone, 0x363d3d373d3d3d363d7300000000000000000000000000000000000000000000)
mstore(add(clone, 0xa), targetBytes)
mstore(add(clone, 0x1e), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
let other := add(clone, 0x40)
extcodecopy(query, other, 0, 0x2d)
result := and(
eq(mload(clone), mload(other)),
eq(mload(add(clone, 0xd)), mload(add(other, 0xd)))
)
}
}
}
文件 14 的 16:Ownable.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function _setOwner(address owner_) internal {
emit OwnershipTransferred(_owner, owner_);
_owner = owner_;
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_setOwner(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
}
}
文件 15 的 16:ShardedWallet.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";
import "../governance/IGovernance.sol";
import "../initializable/Ownable.sol";
import "../initializable/ERC20.sol";
import "../initializable/ERC1363.sol";
contract ShardedWallet is Ownable, ERC20, ERC1363Approve
{
bytes32 public constant ALLOW_GOVERNANCE_UPGRADE = 0xedde61aea0459bc05d70dd3441790ccfb6c17980a380201b00eca6f9ef50452a;
IGovernance public governance;
address public artistWallet;
event Received(address indexed sender, uint256 value, bytes data);
event Execute(address indexed to, uint256 value, bytes data);
event ModuleExecute(address indexed module, address indexed to, uint256 value, bytes data);
event GovernanceUpdated(address indexed oldGovernance, address indexed newGovernance);
event ArtistUpdated(address indexed oldArtist, address indexed newArtist);
modifier onlyModule()
{
require(_isModule(msg.sender), "Access restricted to modules");
_;
}
constructor()
{
governance = IGovernance(address(0xdead));
}
receive()
external payable
{
emit Received(msg.sender, msg.value, bytes(""));
}
fallback()
external payable
{
address module = governance.getModule(address(this), msg.sig);
if (module != address(0) && _isModule(module))
{
(bool success, ) = module.staticcall(msg.data);
assembly {
returndatacopy(0, 0, returndatasize())
switch success
case 0 { revert(0, returndatasize()) }
default { return (0, returndatasize()) }
}
}
else
{
emit Received(msg.sender, msg.value, msg.data);
}
}
function initialize(
address governance_,
address minter_,
string calldata name_,
string calldata symbol_,
address artistWallet_
)
external
{
require(address(governance) == address(0));
governance = IGovernance(governance_);
Ownable._setOwner(minter_);
ERC20._initialize(name_, symbol_);
artistWallet = artistWallet_;
emit GovernanceUpdated(address(0), governance_);
}
function _isModule(address module)
internal view returns (bool)
{
return governance.isModule(address(this), module);
}
function execute(address to, uint256 value, bytes calldata data)
external onlyOwner()
{
Address.functionCallWithValue(to, data, value);
emit Execute(to, value, data);
}
function retrieve(address newOwner)
external
{
ERC20._burn(msg.sender, Math.max(ERC20.totalSupply(), 1));
Ownable._setOwner(newOwner);
}
function moduleExecute(address to, uint256 value, bytes calldata data)
external onlyModule()
{
if (Address.isContract(to))
{
Address.functionCallWithValue(to, data, value);
}
else
{
Address.sendValue(payable(to), value);
}
emit ModuleExecute(msg.sender, to, value, data);
}
function moduleMint(address to, uint256 value)
external onlyModule()
{
ERC20._mint(to, value);
}
function moduleBurn(address from, uint256 value)
external onlyModule()
{
ERC20._burn(from, value);
}
function moduleTransfer(address from, address to, uint256 value)
external onlyModule()
{
ERC20._transfer(from, to, value);
}
function moduleTransferOwnership(address to)
external onlyModule()
{
Ownable._setOwner(to);
}
function updateGovernance(address newGovernance)
external onlyModule()
{
emit GovernanceUpdated(address(governance), newGovernance);
require(governance.getConfig(address(this), ALLOW_GOVERNANCE_UPGRADE) > 0);
require(Address.isContract(newGovernance));
governance = IGovernance(newGovernance);
}
function updateArtistWallet(address newArtistWallet)
external onlyModule()
{
emit ArtistUpdated(artistWallet, newArtistWallet);
artistWallet = newArtistWallet;
}
}
文件 16 的 16:Timers.sol
pragma solidity ^0.8.0;
contract Timers
{
mapping(bytes32 => uint256) private _deadlines;
event TimerStarted(bytes32 indexed timer, uint256 deadline);
event TimerStopped(bytes32 indexed timer);
event TimerReset(bytes32 indexed timer);
modifier onlyBeforeTimer(bytes32 id)
{
require(_beforeTimer(id), "WithTimers: onlyBeforeTimer");
_;
}
modifier onlyDuringTimer(bytes32 id)
{
require(_duringTimer(id), "WithTimers: onlyDuringTimer");
_;
}
modifier onlyAfterTimer(bytes32 id)
{
require(_afterTimer(id), "WithTimers: onlyAfterTimer");
_;
}
function _beforeTimer(bytes32 id)
internal view returns (bool)
{
return _deadlines[id] == 0;
}
function _duringTimer(bytes32 id)
internal view returns (bool)
{
uint256 deadline = _deadlines[id];
return deadline != 0 && deadline > block.timestamp;
}
function _afterTimer(bytes32 id)
internal view returns (bool)
{
uint256 deadline = _deadlines[id];
return deadline != 0 && deadline <= block.timestamp;
}
function _startTimer(bytes32 id, uint256 delay)
internal onlyBeforeTimer(id)
{
uint256 deadline = block.timestamp + delay;
_deadlines[id] = deadline;
emit TimerStarted(id, deadline);
}
function _stopTimer(bytes32 id)
internal onlyDuringTimer(id)
{
delete _deadlines[id];
emit TimerStopped(id);
}
function _resetTimer(bytes32 id)
internal onlyAfterTimer(id)
{
delete _deadlines[id];
emit TimerReset(id);
}
function _getDeadline(bytes32 id)
internal view returns (uint256)
{
return _deadlines[id];
}
}
{
"compilationTarget": {
"contracts/modules/implementations/ActionModule.sol": "ActionModule"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 999
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"walletTemplate","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract ShardedWallet","name":"wallet","type":"address"},{"indexed":true,"internalType":"bytes32","name":"uid","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ActionCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract ShardedWallet","name":"wallet","type":"address"},{"indexed":true,"internalType":"bytes32","name":"uid","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"i","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"ActionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract ShardedWallet","name":"wallet","type":"address"},{"indexed":true,"internalType":"bytes32","name":"uid","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"i","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"ActionScheduled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"timer","type":"bytes32"}],"name":"TimerReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"timer","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"TimerStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"timer","type":"bytes32"}],"name":"TimerStopped","type":"event"},{"inputs":[],"name":"ACTION_AUTH_RATIO","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ACTION_DURATION","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ShardedWallet","name":"wallet","type":"address"},{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"cancel","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ShardedWallet","name":"wallet","type":"address"},{"internalType":"address[]","name":"to","type":"address[]"},{"internalType":"uint256[]","name":"value","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"execute","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ShardedWallet","name":"wallet","type":"address"},{"internalType":"address[]","name":"to","type":"address[]"},{"internalType":"uint256[]","name":"value","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"schedule","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"walletTemplate","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]