Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB 0x87698dc376315b5cef57fe015a9a34a622fa8051.
All metadata displayed below is from that contract. In order to verify current contract, click Verify & Publish button
Verify & Publish
All metadata displayed below is from that contract. In order to verify current contract, click Verify & Publish button
- Contract name:
- Delegator
- Optimization enabled
- true
- Compiler version
- v0.8.17+commit.8df45f5f
- Optimization runs
- 200
- Verified at
- 2025-04-30T20:24:52.302336Z
contracts/governance/Delegator.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.7;
pragma abicoder v2;
// OpenZeppelin v4
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title Delegator
* @author Railgun Contributors
* @notice 'Owner' contract for all railgun contracts
* delegates permissions to other contracts (voter, role)
*/
contract Delegator is Ownable {
/*
Mapping structure is calling address => contract => function signature
0 is used as a wildcard, so permission for contract 0 is permission for
any contract, and permission for function signature 0 is permission for
any function.
Comments below use * to signify wildcard and . notation to separate address/contract/function.
caller.*.* allows caller to call any function on any contract
caller.X.* allows caller to call any function on contract X
caller.*.Y allows caller to call function Y on any contract
*/
mapping(address => mapping(address => mapping(bytes4 => bool))) public permissions;
event GrantPermission(
address indexed caller,
address indexed contractAddress,
bytes4 indexed selector
);
event RevokePermission(
address indexed caller,
address indexed contractAddress,
bytes4 indexed selector
);
/**
* @notice Sets initial admin
*/
constructor(address _admin) {
Ownable.transferOwnership(_admin);
}
/**
* @notice Sets permission bit
* @dev See comment on permissions mapping for wildcard format
* @param _caller - caller to set permissions for
* @param _contract - contract to set permissions for
* @param _selector - selector to set permissions for
* @param _permission - permission bit to set
*/
function setPermission(
address _caller,
address _contract,
bytes4 _selector,
bool _permission
) public onlyOwner {
// If permission set is different to new permission then we execute, otherwise skip
if (permissions[_caller][_contract][_selector] != _permission) {
// Set permission bit
permissions[_caller][_contract][_selector] = _permission;
// Emit event
if (_permission) {
emit GrantPermission(_caller, _contract, _selector);
} else {
emit RevokePermission(_caller, _contract, _selector);
}
}
}
/**
* @notice Checks if caller has permission to execute function
* @param _caller - caller to check permissions for
* @param _contract - contract to check
* @param _selector - function signature to check
* @return if caller has permission
*/
function checkPermission(
address _caller,
address _contract,
bytes4 _selector
) public view returns (bool) {
/*
See comment on permissions mapping for structure
Comments below use * to signify wildcard and . notation to separate contract/function
*/
return (_caller == Ownable.owner() ||
permissions[_caller][_contract][_selector] || // Owner always has global permissions
permissions[_caller][_contract][0x0] || // Permission for function is given
permissions[_caller][address(0)][_selector] || // Permission for _contract.* is given
permissions[_caller][address(0)][0x0]); // Global permission is given
}
/**
* @notice Calls function
* @dev calls to functions on this contract are intercepted and run directly
* this is so the voting contract doesn't need to have special cases for calling
* functions other than this one.
* @param _contract - contract to call
* @param _data - calldata to pass to contract
* @return success - whether call succeeded
* @return returnData - return data from function call
*/
function callContract(
address _contract,
bytes calldata _data,
uint256 _value
) public returns (bool success, bytes memory returnData) {
// Get selector
bytes4 selector = bytes4(_data);
// Intercept calls to this contract
if (_contract == address(this)) {
if (selector == this.setPermission.selector) {
// Decode call data
(address caller, address calledContract, bytes4 _permissionSelector, bool permission) = abi
.decode(abi.encodePacked(_data[4:]), (address, address, bytes4, bool));
// Call setPermission
setPermission(caller, calledContract, _permissionSelector, permission);
// Return success with empty ReturnData bytes
bytes memory empty;
return (true, empty);
} else if (selector == this.transferOwnership.selector) {
// Decode call data
address newOwner = abi.decode(abi.encodePacked(_data[4:]), (address));
// Call transferOwnership
Ownable.transferOwnership(newOwner);
// Return success with empty ReturnData bytes
bytes memory empty;
return (true, empty);
} else if (selector == this.renounceOwnership.selector) {
// Call renounceOwnership
Ownable.renounceOwnership();
// Return success with empty ReturnData bytes
bytes memory empty;
return (true, empty);
} else {
// Return failed with empty ReturnData bytes
bytes memory empty;
return (false, empty);
}
}
// Check permissions
require(
checkPermission(msg.sender, _contract, selector),
"Delegator: Caller doesn't have permission"
);
// Call external contract and return
// solhint-disable-next-line avoid-low-level-calls
return _contract.call{ value: _value }(_data);
}
}
@openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../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.
*
* 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.
*/
abstract 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() {
_transferOwnership(_msgSender());
}
/**
* @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 {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @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 {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_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);
}
}
@openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.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 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;
}
}
Compiler Settings
{"outputSelection":{"*":{"*":["storageLayout","abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"],"":["ast"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_admin","internalType":"address"}]},{"type":"event","name":"GrantPermission","inputs":[{"type":"address","name":"caller","internalType":"address","indexed":true},{"type":"address","name":"contractAddress","internalType":"address","indexed":true},{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RevokePermission","inputs":[{"type":"address","name":"caller","internalType":"address","indexed":true},{"type":"address","name":"contractAddress","internalType":"address","indexed":true},{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"},{"type":"bytes","name":"returnData","internalType":"bytes"}],"name":"callContract","inputs":[{"type":"address","name":"_contract","internalType":"address"},{"type":"bytes","name":"_data","internalType":"bytes"},{"type":"uint256","name":"_value","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"checkPermission","inputs":[{"type":"address","name":"_caller","internalType":"address"},{"type":"address","name":"_contract","internalType":"address"},{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"permissions","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"},{"type":"bytes4","name":"","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPermission","inputs":[{"type":"address","name":"_caller","internalType":"address"},{"type":"address","name":"_contract","internalType":"address"},{"type":"bytes4","name":"_selector","internalType":"bytes4"},{"type":"bool","name":"_permission","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b50604051610ba6380380610ba683398101604081905261002f9161017b565b61003833610051565b61004b816100a160201b6105d11760201c565b506101ab565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6100a961011f565b6001600160a01b0381166101135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61011c81610051565b50565b6000546001600160a01b031633146101795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161010a565b565b60006020828403121561018d57600080fd5b81516001600160a01b03811681146101a457600080fd5b9392505050565b6109ec806101ba6000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80638da5cb5b1161005b5780638da5cb5b146100e8578063c6b295c114610103578063e64624fa14610124578063f2fde38b1461013757600080fd5b8063715018a6146100825780637aa7d3fd1461008c5780638ad2f289146100d5575b600080fd5b61008a61014a565b005b6100c061009a36600461071f565b600160209081526000938452604080852082529284528284209052825290205460ff1681565b60405190151581526020015b60405180910390f35b6100c06100e336600461071f565b61015e565b6000546040516001600160a01b0390911681526020016100cc565b61011661011136600461076a565b610265565b6040516100cc9291906107f5565b61008a61013236600461085b565b610496565b61008a6101453660046108b7565b6105d1565b61015261064a565b61015c60006106a4565b565b600080546001600160a01b03858116911614806101b257506001600160a01b03808516600090815260016020908152604080832093871683529281528282206001600160e01b0319861683529052205460ff165b806101ea57506001600160a01b03808516600090815260016020908152604080832093871683529281528282208280529052205460ff165b8061022a57506001600160a01b038416600090815260016020908152604080832083805282528083206001600160e01b03198616845290915290205460ff165b8061025d57506001600160a01b0384166000908152600160209081526040808320838052825280832090915290205460ff165b949350505050565b600060608161027485876108db565b9050306001600160a01b038816036103bb57630cdced8360e11b6001600160e01b031982160161030a5760008080806102b0896004818d61090b565b6040516020016102c1929190610935565b6040516020818303038152906040528060200190518101906102e39190610945565b93509350935093506102f784848484610496565b50600195506060945061048d9350505050565b630d021c7560e01b6001600160e01b031982160161037f576000610331866004818a61090b565b604051602001610342929190610935565b6040516020818303038152906040528060200190518101906103649190610999565b905061036f816105d1565b50600192506060915061048d9050565b634757f3ad60e11b6001600160e01b03198216016103ad5761039f61014a565b50600191506060905061048d565b50600091506060905061048d565b6103c633888361015e565b6104295760405162461bcd60e51b815260206004820152602960248201527f44656c656761746f723a2043616c6c657220646f65736e27742068617665207060448201526832b936b4b9b9b4b7b760b91b60648201526084015b60405180910390fd5b866001600160a01b0316848787604051610444929190610935565b60006040518083038185875af1925050503d8060008114610481576040519150601f19603f3d011682016040523d82523d6000602084013e610486565b606091505b5092509250505b94509492505050565b61049e61064a565b6001600160a01b03808516600090815260016020908152604080832093871683529281528282206001600160e01b0319861683529052205460ff161515811515146105cb576001600160a01b03848116600090815260016020908152604080832093871683529281528282206001600160e01b031986168352905220805460ff1916821580159190911790915561057f57816001600160e01b031916836001600160a01b0316856001600160a01b03167f521b363b3401f4d6404e4bd855a3edf8d254a7f55abb97b6d516b66a6f86205e60405160405180910390a46105cb565b816001600160e01b031916836001600160a01b0316856001600160a01b03167f91f81f13bab4e6573f47dda4f090782eb2c9173d3d489ca191b5f4f7355cebe860405160405180910390a45b50505050565b6105d961064a565b6001600160a01b03811661063e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610420565b610647816106a4565b50565b6000546001600160a01b0316331461015c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610420565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116811461064757600080fd5b6001600160e01b03198116811461064757600080fd5b60008060006060848603121561073457600080fd5b833561073f816106f4565b9250602084013561074f816106f4565b9150604084013561075f81610709565b809150509250925092565b6000806000806060858703121561078057600080fd5b843561078b816106f4565b9350602085013567ffffffffffffffff808211156107a857600080fd5b818701915087601f8301126107bc57600080fd5b8135818111156107cb57600080fd5b8860208285010111156107dd57600080fd5b95986020929092019750949560400135945092505050565b821515815260006020604081840152835180604085015260005b8181101561082b5785810183015185820160600152820161080f565b506000606082860101526060601f19601f830116850101925050509392505050565b801515811461064757600080fd5b6000806000806080858703121561087157600080fd5b843561087c816106f4565b9350602085013561088c816106f4565b9250604085013561089c81610709565b915060608501356108ac8161084d565b939692955090935050565b6000602082840312156108c957600080fd5b81356108d4816106f4565b9392505050565b6001600160e01b031981358181169160048510156109035780818660040360031b1b83161692505b505092915050565b6000808585111561091b57600080fd5b8386111561092857600080fd5b5050820193919092039150565b8183823760009101908152919050565b6000806000806080858703121561095b57600080fd5b8451610966816106f4565b6020860151909450610977816106f4565b604086015190935061098881610709565b60608601519092506108ac8161084d565b6000602082840312156109ab57600080fd5b81516108d4816106f456fea264697066735822122043b62f587bd1dd4f8e47ec71a8974d9f9dc756c63e4261c8e945fd0e1d8cd82364736f6c63430008110033000000000000000000000000b94333ca4de54f79b24294582471c9c336acb7c0
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80638da5cb5b1161005b5780638da5cb5b146100e8578063c6b295c114610103578063e64624fa14610124578063f2fde38b1461013757600080fd5b8063715018a6146100825780637aa7d3fd1461008c5780638ad2f289146100d5575b600080fd5b61008a61014a565b005b6100c061009a36600461071f565b600160209081526000938452604080852082529284528284209052825290205460ff1681565b60405190151581526020015b60405180910390f35b6100c06100e336600461071f565b61015e565b6000546040516001600160a01b0390911681526020016100cc565b61011661011136600461076a565b610265565b6040516100cc9291906107f5565b61008a61013236600461085b565b610496565b61008a6101453660046108b7565b6105d1565b61015261064a565b61015c60006106a4565b565b600080546001600160a01b03858116911614806101b257506001600160a01b03808516600090815260016020908152604080832093871683529281528282206001600160e01b0319861683529052205460ff165b806101ea57506001600160a01b03808516600090815260016020908152604080832093871683529281528282208280529052205460ff165b8061022a57506001600160a01b038416600090815260016020908152604080832083805282528083206001600160e01b03198616845290915290205460ff165b8061025d57506001600160a01b0384166000908152600160209081526040808320838052825280832090915290205460ff165b949350505050565b600060608161027485876108db565b9050306001600160a01b038816036103bb57630cdced8360e11b6001600160e01b031982160161030a5760008080806102b0896004818d61090b565b6040516020016102c1929190610935565b6040516020818303038152906040528060200190518101906102e39190610945565b93509350935093506102f784848484610496565b50600195506060945061048d9350505050565b630d021c7560e01b6001600160e01b031982160161037f576000610331866004818a61090b565b604051602001610342929190610935565b6040516020818303038152906040528060200190518101906103649190610999565b905061036f816105d1565b50600192506060915061048d9050565b634757f3ad60e11b6001600160e01b03198216016103ad5761039f61014a565b50600191506060905061048d565b50600091506060905061048d565b6103c633888361015e565b6104295760405162461bcd60e51b815260206004820152602960248201527f44656c656761746f723a2043616c6c657220646f65736e27742068617665207060448201526832b936b4b9b9b4b7b760b91b60648201526084015b60405180910390fd5b866001600160a01b0316848787604051610444929190610935565b60006040518083038185875af1925050503d8060008114610481576040519150601f19603f3d011682016040523d82523d6000602084013e610486565b606091505b5092509250505b94509492505050565b61049e61064a565b6001600160a01b03808516600090815260016020908152604080832093871683529281528282206001600160e01b0319861683529052205460ff161515811515146105cb576001600160a01b03848116600090815260016020908152604080832093871683529281528282206001600160e01b031986168352905220805460ff1916821580159190911790915561057f57816001600160e01b031916836001600160a01b0316856001600160a01b03167f521b363b3401f4d6404e4bd855a3edf8d254a7f55abb97b6d516b66a6f86205e60405160405180910390a46105cb565b816001600160e01b031916836001600160a01b0316856001600160a01b03167f91f81f13bab4e6573f47dda4f090782eb2c9173d3d489ca191b5f4f7355cebe860405160405180910390a45b50505050565b6105d961064a565b6001600160a01b03811661063e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610420565b610647816106a4565b50565b6000546001600160a01b0316331461015c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610420565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116811461064757600080fd5b6001600160e01b03198116811461064757600080fd5b60008060006060848603121561073457600080fd5b833561073f816106f4565b9250602084013561074f816106f4565b9150604084013561075f81610709565b809150509250925092565b6000806000806060858703121561078057600080fd5b843561078b816106f4565b9350602085013567ffffffffffffffff808211156107a857600080fd5b818701915087601f8301126107bc57600080fd5b8135818111156107cb57600080fd5b8860208285010111156107dd57600080fd5b95986020929092019750949560400135945092505050565b821515815260006020604081840152835180604085015260005b8181101561082b5785810183015185820160600152820161080f565b506000606082860101526060601f19601f830116850101925050509392505050565b801515811461064757600080fd5b6000806000806080858703121561087157600080fd5b843561087c816106f4565b9350602085013561088c816106f4565b9250604085013561089c81610709565b915060608501356108ac8161084d565b939692955090935050565b6000602082840312156108c957600080fd5b81356108d4816106f4565b9392505050565b6001600160e01b031981358181169160048510156109035780818660040360031b1b83161692505b505092915050565b6000808585111561091b57600080fd5b8386111561092857600080fd5b5050820193919092039150565b8183823760009101908152919050565b6000806000806080858703121561095b57600080fd5b8451610966816106f4565b6020860151909450610977816106f4565b604086015190935061098881610709565b60608601519092506108ac8161084d565b6000602082840312156109ab57600080fd5b81516108d4816106f456fea264697066735822122043b62f587bd1dd4f8e47ec71a8974d9f9dc756c63e4261c8e945fd0e1d8cd82364736f6c63430008110033