- Contract name:
- ERC1538UpdateDelegate
- Optimization enabled
- true
- Compiler version
- v0.6.4+commit.1dca32f3
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-08-06T07:58:25.518344Z
Contract source code
pragma solidity ^0.6.0; /* * @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 GSN 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. */ contract Context { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor () internal { } function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } /** * @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. * * By default, the owner account will be the one that deploys the contract. 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. */ contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = 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 { _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). */ function _transferOwnership(address newOwner) internal virtual { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } library LibSet_bytes4 { struct set { bytes4[] values; mapping(bytes4 => uint256) indexes; } function length(set storage _set) internal view returns (uint256) { return _set.values.length; } function at(set storage _set, uint256 _index) internal view returns (bytes4 ) { return _set.values[_index - 1]; } function indexOf(set storage _set, bytes4 _value) internal view returns (uint256) { return _set.indexes[_value]; } function contains(set storage _set, bytes4 _value) internal view returns (bool) { return indexOf(_set, _value) != 0; } function content(set storage _set) internal view returns (bytes4[] memory) { return _set.values; } function add(set storage _set, bytes4 _value) internal returns (bool) { if (contains(_set, _value)) { return false; } _set.values.push(_value); _set.indexes[_value] = _set.values.length; return true; } function remove(set storage _set, bytes4 _value) internal returns (bool) { if (!contains(_set, _value)) { return false; } uint256 i = indexOf(_set, _value); uint256 last = length(_set); if (i != last) { bytes4 swapValue = _set.values[last - 1]; _set.values[i - 1] = swapValue; _set.indexes[swapValue] = i; } delete _set.indexes[_value]; _set.values.pop(); return true; } function clear(set storage _set) internal returns (bool) { for (uint256 i = _set.values.length; i > 0; --i) { delete _set.indexes[_set.values[i-1]]; } _set.values = new bytes4[](0); return true; } } library LibMap2_bytes4_address_bytes { using LibSet_bytes4 for LibSet_bytes4.set; struct map { LibSet_bytes4.set keyset; mapping(bytes4 => address) values1; mapping(bytes4 => bytes) values2; } function length(map storage _map) internal view returns (uint256) { return _map.keyset.length(); } function value1(map storage _map, bytes4 _key) internal view returns (address ) { return _map.values1[_key]; } function value2(map storage _map, bytes4 _key) internal view returns (bytes memory) { return _map.values2[_key]; } function keyAt(map storage _map, uint256 _index) internal view returns (bytes4 ) { return _map.keyset.at(_index); } function at(map storage _map, uint256 _index) internal view returns (bytes4 , address , bytes memory) { bytes4 key = keyAt(_map, _index); return (key, value1(_map, key), value2(_map, key)); } function indexOf(map storage _map, bytes4 _key) internal view returns (uint256) { return _map.keyset.indexOf(_key); } function contains(map storage _map, bytes4 _key) internal view returns (bool) { return _map.keyset.contains(_key); } function keys(map storage _map) internal view returns (bytes4[] memory) { return _map.keyset.content(); } function set( map storage _map, bytes4 _key, address _value1, bytes memory _value2) internal returns (bool) { _map.keyset.add(_key); _map.values1[_key] = _value1; _map.values2[_key] = _value2; return true; } function del(map storage _map, bytes4 _key) internal returns (bool) { _map.keyset.remove(_key); delete _map.values1[_key]; delete _map.values2[_key]; return true; } function clear(map storage _map) internal returns (bool) { for (uint256 i = _map.keyset.length(); i > 0; --i) { bytes4 key = keyAt(_map, i); delete _map.values1[key]; delete _map.values2[key]; } _map.keyset.clear(); return true; } } interface IERC1538 { event CommitMessage(string message); event FunctionUpdate(bytes4 indexed functionId, address indexed oldDelegate, address indexed newDelegate, string functionSignature); } contract ERC1538Store is Ownable { using LibMap2_bytes4_address_bytes for LibMap2_bytes4_address_bytes.map; LibMap2_bytes4_address_bytes.map internal m_funcs; } contract ERC1538Core is IERC1538, ERC1538Store { bytes4 constant internal RECEIVE = 0xd217fcc6; // bytes4(keccak256("receive")); bytes4 constant internal FALLBACK = 0xb32cdf4d; // bytes4(keccak256("fallback")); event CommitMessage(string message); event FunctionUpdate(bytes4 indexed functionId, address indexed oldDelegate, address indexed newDelegate, string functionSignature); function _setFunc(string memory funcSignature, address funcDelegate) internal { bytes4 funcId = bytes4(keccak256(bytes(funcSignature))); if (funcId == RECEIVE ) { funcId = bytes4(0x00000000); } if (funcId == FALLBACK) { funcId = bytes4(0xFFFFFFFF); } address oldDelegate = m_funcs.value1(funcId); if (funcDelegate == oldDelegate) // No change → skip { return; } else if (funcDelegate == address(0)) // Delete { m_funcs.del(funcId); } else // Set / Update { m_funcs.set(funcId, funcDelegate, bytes(funcSignature)); } emit FunctionUpdate(funcId, oldDelegate, funcDelegate, funcSignature); } } contract ERC1538Module is ERC1538Store { constructor() public { renounceOwnership(); } } interface ERC1538Update { function updateContract(address _delegate, string calldata _functionSignatures, string calldata commitMessage) external; } contract ERC1538UpdateDelegate is ERC1538Update, ERC1538Core, ERC1538Module { function updateContract( address _delegate, string calldata _functionSignatures, string calldata _commitMessage ) external override onlyOwner { bytes memory signatures = bytes(_functionSignatures); uint256 start; uint256 end; uint256 size; if (_delegate != address(0)) { assembly { size := extcodesize(_delegate) } require(size > 0, "[ERC1538] _delegate address is not a contract and is not address(0)"); } assembly { start := add(signatures, 32) end := add(start, mload(signatures)) } for (uint256 pos = start; pos < end; ++pos) { uint256 char; assembly { char := byte(0, mload(pos)) } if (char == 0x3B) // 0x3B = ';' { uint256 length = (pos - start); assembly { mstore(signatures, length) } _setFunc(string(signatures), _delegate); assembly { signatures := add(signatures, add(length, 1)) } start = pos+1; } } emit CommitMessage(_commitMessage); } }
Contract ABI
[{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateContract","inputs":[{"type":"address","name":"_delegate","internalType":"address"},{"type":"string","name":"_functionSignatures","internalType":"string"},{"type":"string","name":"_commitMessage","internalType":"string"}]},{"type":"event","name":"CommitMessage","inputs":[{"type":"string","name":"message","indexed":false}],"anonymous":false},{"type":"event","name":"FunctionUpdate","inputs":[{"type":"bytes4","name":"functionId","indexed":true},{"type":"address","name":"oldDelegate","indexed":true},{"type":"address","name":"newDelegate","indexed":true},{"type":"string","name":"functionSignature","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","indexed":true},{"type":"address","name":"newOwner","indexed":true}],"anonymous":false}]
Contract Creation Code
0x608060405260006100176001600160e01b0361006516565b600080546001600160a01b0319166001600160a01b038316908117825560405192935091600080516020610c09833981519152908290a3506100606001600160e01b0361006916565b610114565b3390565b61007a6001600160e01b0361006516565b6000546001600160a01b039081169116146100dc576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b0390911690600080516020610c09833981519152908390a3600080546001600160a01b0319169055565b610ae6806101236000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80636145556714610051578063715018a6146101255780638da5cb5b1461012d578063f2fde38b14610151575b600080fd5b6101236004803603606081101561006757600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561009257600080fd5b8201836020820111156100a457600080fd5b803590602001918460018302840111640100000000831117156100c657600080fd5b9193909290916020810190356401000000008111156100e457600080fd5b8201836020820111156100f657600080fd5b8035906020019184600183028401116401000000008311171561011857600080fd5b509092509050610177565b005b61012361032a565b6101356103de565b604080516001600160a01b039092168252519081900360200190f35b6101236004803603602081101561016757600080fd5b50356001600160a01b03166103ee565b61017f610464565b6000546001600160a01b039081169116146101e1576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250939450839250829150506001600160a01b0389161561026d5750873b8061026d5760405162461bcd60e51b8152600401808060200182810382526043815260200180610a6e6043913960600191505060405180910390fd5b60208401925083518301915060008390505b828110156102be57805160001a603b8114156102b5578482038087526102a5878d610468565b6001810187019650826001019550505b5060010161027f565b507faa1c0a0a78cec2470f9652e5d29540752e7a64d70f926933cebf13afaeda45de868660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a1505050505050505050565b610332610464565b6000546001600160a01b03908116911614610394576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b03165b90565b6103f6610464565b6000546001600160a01b03908116911614610458576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b610461816105df565b50565b3390565b815160208301206001600160e01b0319811663690bfe6360e11b141561048c575060005b6001600160e01b0319811663b32cdf4d60e01b14156104b057506001600160e01b03195b60006104c360018363ffffffff61067f16565b9050806001600160a01b0316836001600160a01b031614156104e65750506105db565b6001600160a01b03831661050b5761050560018363ffffffff6106ab16565b50610520565b61051e600183858763ffffffff61070516565b505b826001600160a01b0316816001600160a01b0316836001600160e01b0319167f3234040ce3bd4564874e44810f198910133a1b24c4e84aac87edbf6b458f5353876040518080602001828103825283818151815260200191508051906020019080838360005b8381101561059e578181015183820152602001610586565b50505050905090810190601f1680156105cb5780820380516001836020036101000a031916815260200191505b509250505060405180910390a450505b5050565b6001600160a01b0381166106245760405162461bcd60e51b8152600401808060200182810382526026815260200180610a486026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160e01b0319811660009081526002830160205260409020546001600160a01b03165b92915050565b60006106bd838363ffffffff61077216565b506001600160e01b031982166000908152600284016020908152604080832080546001600160a01b03191690556003860190915281206106fc9161096b565b50600192915050565b6000610717858563ffffffff6108b916565b506001600160e01b031984166000908152600286016020908152604080832080546001600160a01b0319166001600160a01b0388161790556003880182529091208351610766928501906109af565b50600195945050505050565b600061077e8383610932565b61078a575060006106a5565b60006107968484610947565b905060006107a385610967565b90508082146108585760008560000160018303815481106107c057fe5b90600052602060002090600891828204019190066004029054906101000a900460e01b9050808660000160018503815481106107f857fe5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908360e01c021790555082866001016000836001600160e01b0319166001600160e01b031916815260200190815260200160002081905550505b6001600160e01b031984166000908152600186016020526040812055845485908061087f57fe5b600082815260209020600860001990920191820401805463ffffffff600460078516026101000a0219169055905550600191505092915050565b60006108c58383610932565b156108d2575060006106a5565b50815460018082018455600084815260208082206008850401805463ffffffff60079096166004026101000a958602191660e087901c959095029490941790935584546001600160e01b0319909416815293810190915260409092205590565b600061093e8383610947565b15159392505050565b6001600160e01b0319166000908152600191909101602052604090205490565b5490565b50805460018160011615610100020316600290046000825580601f106109915750610461565b601f0160209004906000526020600020908101906104619190610a2d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106109f057805160ff1916838001178555610a1d565b82800160010185558215610a1d579182015b82811115610a1d578251825591602001919060010190610a02565b50610a29929150610a2d565b5090565b6103eb91905b80821115610a295760008155600101610a3356fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735b455243313533385d205f64656c65676174652061646472657373206973206e6f74206120636f6e747261637420616e64206973206e6f742061646472657373283029a2646970667358221220ad7328f46f719b895046b880aef2dd7e0af9f6c04510d21a00e3c8bd9941103564736f6c634300060400338be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80636145556714610051578063715018a6146101255780638da5cb5b1461012d578063f2fde38b14610151575b600080fd5b6101236004803603606081101561006757600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561009257600080fd5b8201836020820111156100a457600080fd5b803590602001918460018302840111640100000000831117156100c657600080fd5b9193909290916020810190356401000000008111156100e457600080fd5b8201836020820111156100f657600080fd5b8035906020019184600183028401116401000000008311171561011857600080fd5b509092509050610177565b005b61012361032a565b6101356103de565b604080516001600160a01b039092168252519081900360200190f35b6101236004803603602081101561016757600080fd5b50356001600160a01b03166103ee565b61017f610464565b6000546001600160a01b039081169116146101e1576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250939450839250829150506001600160a01b0389161561026d5750873b8061026d5760405162461bcd60e51b8152600401808060200182810382526043815260200180610a6e6043913960600191505060405180910390fd5b60208401925083518301915060008390505b828110156102be57805160001a603b8114156102b5578482038087526102a5878d610468565b6001810187019650826001019550505b5060010161027f565b507faa1c0a0a78cec2470f9652e5d29540752e7a64d70f926933cebf13afaeda45de868660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a1505050505050505050565b610332610464565b6000546001600160a01b03908116911614610394576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b03165b90565b6103f6610464565b6000546001600160a01b03908116911614610458576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b610461816105df565b50565b3390565b815160208301206001600160e01b0319811663690bfe6360e11b141561048c575060005b6001600160e01b0319811663b32cdf4d60e01b14156104b057506001600160e01b03195b60006104c360018363ffffffff61067f16565b9050806001600160a01b0316836001600160a01b031614156104e65750506105db565b6001600160a01b03831661050b5761050560018363ffffffff6106ab16565b50610520565b61051e600183858763ffffffff61070516565b505b826001600160a01b0316816001600160a01b0316836001600160e01b0319167f3234040ce3bd4564874e44810f198910133a1b24c4e84aac87edbf6b458f5353876040518080602001828103825283818151815260200191508051906020019080838360005b8381101561059e578181015183820152602001610586565b50505050905090810190601f1680156105cb5780820380516001836020036101000a031916815260200191505b509250505060405180910390a450505b5050565b6001600160a01b0381166106245760405162461bcd60e51b8152600401808060200182810382526026815260200180610a486026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160e01b0319811660009081526002830160205260409020546001600160a01b03165b92915050565b60006106bd838363ffffffff61077216565b506001600160e01b031982166000908152600284016020908152604080832080546001600160a01b03191690556003860190915281206106fc9161096b565b50600192915050565b6000610717858563ffffffff6108b916565b506001600160e01b031984166000908152600286016020908152604080832080546001600160a01b0319166001600160a01b0388161790556003880182529091208351610766928501906109af565b50600195945050505050565b600061077e8383610932565b61078a575060006106a5565b60006107968484610947565b905060006107a385610967565b90508082146108585760008560000160018303815481106107c057fe5b90600052602060002090600891828204019190066004029054906101000a900460e01b9050808660000160018503815481106107f857fe5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908360e01c021790555082866001016000836001600160e01b0319166001600160e01b031916815260200190815260200160002081905550505b6001600160e01b031984166000908152600186016020526040812055845485908061087f57fe5b600082815260209020600860001990920191820401805463ffffffff600460078516026101000a0219169055905550600191505092915050565b60006108c58383610932565b156108d2575060006106a5565b50815460018082018455600084815260208082206008850401805463ffffffff60079096166004026101000a958602191660e087901c959095029490941790935584546001600160e01b0319909416815293810190915260409092205590565b600061093e8383610947565b15159392505050565b6001600160e01b0319166000908152600191909101602052604090205490565b5490565b50805460018160011615610100020316600290046000825580601f106109915750610461565b601f0160209004906000526020600020908101906104619190610a2d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106109f057805160ff1916838001178555610a1d565b82800160010185558215610a1d579182015b82811115610a1d578251825591602001919060010190610a02565b50610a29929150610a2d565b5090565b6103eb91905b80821115610a295760008155600101610a3356fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735b455243313533385d205f64656c65676174652061646472657373206973206e6f74206120636f6e747261637420616e64206973206e6f742061646472657373283029a2646970667358221220ad7328f46f719b895046b880aef2dd7e0af9f6c04510d21a00e3c8bd9941103564736f6c63430006040033