false
true
0

Contract Address Details

0x9F95ec66321A392DA3A440eee7d9fCE2e25a6A02

Contract Name
Delegator
Creator
0xb94333–acb7c0 at 0xb931ba–be4276
Balance
0 tPLS
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
25429072
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
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

Verify & Publish
0x608060405234801561001057600080fd5b50604051610ba6380380610ba683398101604081905261002f9161017b565b61003833610051565b61004b816100a160201b6105d11760201c565b506101ab565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6100a961011f565b6001600160a01b0381166101135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61011c81610051565b50565b6000546001600160a01b031633146101795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161010a565b565b60006020828403121561018d57600080fd5b81516001600160a01b03811681146101a457600080fd5b9392505050565b6109ec806101ba6000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80638da5cb5b1161005b5780638da5cb5b146100e8578063c6b295c114610103578063e64624fa14610124578063f2fde38b1461013757600080fd5b8063715018a6146100825780637aa7d3fd1461008c5780638ad2f289146100d5575b600080fd5b61008a61014a565b005b6100c061009a36600461071f565b600160209081526000938452604080852082529284528284209052825290205460ff1681565b60405190151581526020015b60405180910390f35b6100c06100e336600461071f565b61015e565b6000546040516001600160a01b0390911681526020016100cc565b61011661011136600461076a565b610265565b6040516100cc9291906107f5565b61008a61013236600461085b565b610496565b61008a6101453660046108b7565b6105d1565b61015261064a565b61015c60006106a4565b565b600080546001600160a01b03858116911614806101b257506001600160a01b03808516600090815260016020908152604080832093871683529281528282206001600160e01b0319861683529052205460ff165b806101ea57506001600160a01b03808516600090815260016020908152604080832093871683529281528282208280529052205460ff165b8061022a57506001600160a01b038416600090815260016020908152604080832083805282528083206001600160e01b03198616845290915290205460ff165b8061025d57506001600160a01b0384166000908152600160209081526040808320838052825280832090915290205460ff165b949350505050565b600060608161027485876108db565b9050306001600160a01b038816036103bb57630cdced8360e11b6001600160e01b031982160161030a5760008080806102b0896004818d61090b565b6040516020016102c1929190610935565b6040516020818303038152906040528060200190518101906102e39190610945565b93509350935093506102f784848484610496565b50600195506060945061048d9350505050565b630d021c7560e01b6001600160e01b031982160161037f576000610331866004818a61090b565b604051602001610342929190610935565b6040516020818303038152906040528060200190518101906103649190610999565b905061036f816105d1565b50600192506060915061048d9050565b634757f3ad60e11b6001600160e01b03198216016103ad5761039f61014a565b50600191506060905061048d565b50600091506060905061048d565b6103c633888361015e565b6104295760405162461bcd60e51b815260206004820152602960248201527f44656c656761746f723a2043616c6c657220646f65736e27742068617665207060448201526832b936b4b9b9b4b7b760b91b60648201526084015b60405180910390fd5b866001600160a01b0316848787604051610444929190610935565b60006040518083038185875af1925050503d8060008114610481576040519150601f19603f3d011682016040523d82523d6000602084013e610486565b606091505b5092509250505b94509492505050565b61049e61064a565b6001600160a01b03808516600090815260016020908152604080832093871683529281528282206001600160e01b0319861683529052205460ff161515811515146105cb576001600160a01b03848116600090815260016020908152604080832093871683529281528282206001600160e01b031986168352905220805460ff1916821580159190911790915561057f57816001600160e01b031916836001600160a01b0316856001600160a01b03167f521b363b3401f4d6404e4bd855a3edf8d254a7f55abb97b6d516b66a6f86205e60405160405180910390a46105cb565b816001600160e01b031916836001600160a01b0316856001600160a01b03167f91f81f13bab4e6573f47dda4f090782eb2c9173d3d489ca191b5f4f7355cebe860405160405180910390a45b50505050565b6105d961064a565b6001600160a01b03811661063e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610420565b610647816106a4565b50565b6000546001600160a01b0316331461015c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610420565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116811461064757600080fd5b6001600160e01b03198116811461064757600080fd5b60008060006060848603121561073457600080fd5b833561073f816106f4565b9250602084013561074f816106f4565b9150604084013561075f81610709565b809150509250925092565b6000806000806060858703121561078057600080fd5b843561078b816106f4565b9350602085013567ffffffffffffffff808211156107a857600080fd5b818701915087601f8301126107bc57600080fd5b8135818111156107cb57600080fd5b8860208285010111156107dd57600080fd5b95986020929092019750949560400135945092505050565b821515815260006020604081840152835180604085015260005b8181101561082b5785810183015185820160600152820161080f565b506000606082860101526060601f19601f830116850101925050509392505050565b801515811461064757600080fd5b6000806000806080858703121561087157600080fd5b843561087c816106f4565b9350602085013561088c816106f4565b9250604085013561089c81610709565b915060608501356108ac8161084d565b939692955090935050565b6000602082840312156108c957600080fd5b81356108d4816106f4565b9392505050565b6001600160e01b031981358181169160048510156109035780818660040360031b1b83161692505b505092915050565b6000808585111561091b57600080fd5b8386111561092857600080fd5b5050820193919092039150565b8183823760009101908152919050565b6000806000806080858703121561095b57600080fd5b8451610966816106f4565b6020860151909450610977816106f4565b604086015190935061098881610709565b60608601519092506108ac8161084d565b6000602082840312156109ab57600080fd5b81516108d4816106f456fea264697066735822122043b62f587bd1dd4f8e47ec71a8974d9f9dc756c63e4261c8e945fd0e1d8cd82364736f6c63430008110033000000000000000000000000b94333ca4de54f79b24294582471c9c336acb7c0

Deployed ByteCode

0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80638da5cb5b1161005b5780638da5cb5b146100e8578063c6b295c114610103578063e64624fa14610124578063f2fde38b1461013757600080fd5b8063715018a6146100825780637aa7d3fd1461008c5780638ad2f289146100d5575b600080fd5b61008a61014a565b005b6100c061009a36600461071f565b600160209081526000938452604080852082529284528284209052825290205460ff1681565b60405190151581526020015b60405180910390f35b6100c06100e336600461071f565b61015e565b6000546040516001600160a01b0390911681526020016100cc565b61011661011136600461076a565b610265565b6040516100cc9291906107f5565b61008a61013236600461085b565b610496565b61008a6101453660046108b7565b6105d1565b61015261064a565b61015c60006106a4565b565b600080546001600160a01b03858116911614806101b257506001600160a01b03808516600090815260016020908152604080832093871683529281528282206001600160e01b0319861683529052205460ff165b806101ea57506001600160a01b03808516600090815260016020908152604080832093871683529281528282208280529052205460ff165b8061022a57506001600160a01b038416600090815260016020908152604080832083805282528083206001600160e01b03198616845290915290205460ff165b8061025d57506001600160a01b0384166000908152600160209081526040808320838052825280832090915290205460ff165b949350505050565b600060608161027485876108db565b9050306001600160a01b038816036103bb57630cdced8360e11b6001600160e01b031982160161030a5760008080806102b0896004818d61090b565b6040516020016102c1929190610935565b6040516020818303038152906040528060200190518101906102e39190610945565b93509350935093506102f784848484610496565b50600195506060945061048d9350505050565b630d021c7560e01b6001600160e01b031982160161037f576000610331866004818a61090b565b604051602001610342929190610935565b6040516020818303038152906040528060200190518101906103649190610999565b905061036f816105d1565b50600192506060915061048d9050565b634757f3ad60e11b6001600160e01b03198216016103ad5761039f61014a565b50600191506060905061048d565b50600091506060905061048d565b6103c633888361015e565b6104295760405162461bcd60e51b815260206004820152602960248201527f44656c656761746f723a2043616c6c657220646f65736e27742068617665207060448201526832b936b4b9b9b4b7b760b91b60648201526084015b60405180910390fd5b866001600160a01b0316848787604051610444929190610935565b60006040518083038185875af1925050503d8060008114610481576040519150601f19603f3d011682016040523d82523d6000602084013e610486565b606091505b5092509250505b94509492505050565b61049e61064a565b6001600160a01b03808516600090815260016020908152604080832093871683529281528282206001600160e01b0319861683529052205460ff161515811515146105cb576001600160a01b03848116600090815260016020908152604080832093871683529281528282206001600160e01b031986168352905220805460ff1916821580159190911790915561057f57816001600160e01b031916836001600160a01b0316856001600160a01b03167f521b363b3401f4d6404e4bd855a3edf8d254a7f55abb97b6d516b66a6f86205e60405160405180910390a46105cb565b816001600160e01b031916836001600160a01b0316856001600160a01b03167f91f81f13bab4e6573f47dda4f090782eb2c9173d3d489ca191b5f4f7355cebe860405160405180910390a45b50505050565b6105d961064a565b6001600160a01b03811661063e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610420565b610647816106a4565b50565b6000546001600160a01b0316331461015c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610420565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116811461064757600080fd5b6001600160e01b03198116811461064757600080fd5b60008060006060848603121561073457600080fd5b833561073f816106f4565b9250602084013561074f816106f4565b9150604084013561075f81610709565b809150509250925092565b6000806000806060858703121561078057600080fd5b843561078b816106f4565b9350602085013567ffffffffffffffff808211156107a857600080fd5b818701915087601f8301126107bc57600080fd5b8135818111156107cb57600080fd5b8860208285010111156107dd57600080fd5b95986020929092019750949560400135945092505050565b821515815260006020604081840152835180604085015260005b8181101561082b5785810183015185820160600152820161080f565b506000606082860101526060601f19601f830116850101925050509392505050565b801515811461064757600080fd5b6000806000806080858703121561087157600080fd5b843561087c816106f4565b9350602085013561088c816106f4565b9250604085013561089c81610709565b915060608501356108ac8161084d565b939692955090935050565b6000602082840312156108c957600080fd5b81356108d4816106f4565b9392505050565b6001600160e01b031981358181169160048510156109035780818660040360031b1b83161692505b505092915050565b6000808585111561091b57600080fd5b8386111561092857600080fd5b5050820193919092039150565b8183823760009101908152919050565b6000806000806080858703121561095b57600080fd5b8451610966816106f4565b6020860151909450610977816106f4565b604086015190935061098881610709565b60608601519092506108ac8161084d565b6000602082840312156109ab57600080fd5b81516108d4816106f456fea264697066735822122043b62f587bd1dd4f8e47ec71a8974d9f9dc756c63e4261c8e945fd0e1d8cd82364736f6c63430008110033