Feature Tip: Add private address tag to any address under My Name Tag !
ERC-20
Overview
Max Total Supply
1,126.687931099999983002 CUSD
Holders
55
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
0.999999999999999955 CUSDValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
CarbonDollarProxy
Compiler Version
v0.4.24+commit.e67f0147
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2018-09-28 */ pragma solidity ^0.4.24; /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ library SafeMath { /** * @dev Multiplies two numbers, throws on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { // Gas optimization: this is cheaper than asserting 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } c = a * b; assert(c / a == b); return c; } /** * @dev Integer division of two numbers, truncating the quotient. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 // uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return a / b; } /** * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } /** * @dev Adds two numbers, throws on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a + b; assert(c >= a); return c; } } /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". This adds two-phase * ownership control to OpenZeppelin's Ownable class. In this model, the original owner * designates a new owner but does not actually transfer ownership. The new owner then accepts * ownership and completes the transfer. */ contract Ownable { address public owner; address public pendingOwner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor() public { owner = msg.sender; pendingOwner = address(0); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner); _; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyPendingOwner() { require(msg.sender == pendingOwner); _; } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param _newOwner The address to transfer ownership to. */ function transferOwnership(address _newOwner) public onlyOwner { require(_newOwner != address(0)); pendingOwner = _newOwner; } /** * @dev Allows the pendingOwner address to finalize the transfer. */ function claimOwnership() onlyPendingOwner public { emit OwnershipTransferred(owner, pendingOwner); owner = pendingOwner; pendingOwner = address(0); } } /** * @title CarbonDollarStorage * @notice Contains necessary storage contracts for CarbonDollar (FeeSheet and StablecoinWhitelist). */ contract CarbonDollarStorage is Ownable { using SafeMath for uint256; /** Mappings */ /* fees for withdrawing to stablecoin, in tenths of a percent) */ mapping (address => uint256) public fees; /** @dev Units for fees are always in a tenth of a percent */ uint256 public defaultFee; /* is the token address referring to a stablecoin/whitelisted token? */ mapping (address => bool) public whitelist; /** Events */ event DefaultFeeChanged(uint256 oldFee, uint256 newFee); event FeeChanged(address indexed stablecoin, uint256 oldFee, uint256 newFee); event FeeRemoved(address indexed stablecoin, uint256 oldFee); event StablecoinAdded(address indexed stablecoin); event StablecoinRemoved(address indexed stablecoin); /** @notice Sets the default fee for burning CarbonDollar into a whitelisted stablecoin. @param _fee The default fee. */ function setDefaultFee(uint256 _fee) public onlyOwner { uint256 oldFee = defaultFee; defaultFee = _fee; if (oldFee != defaultFee) emit DefaultFeeChanged(oldFee, _fee); } /** @notice Set a fee for burning CarbonDollar into a stablecoin. @param _stablecoin Address of a whitelisted stablecoin. @param _fee the fee. */ function setFee(address _stablecoin, uint256 _fee) public onlyOwner { uint256 oldFee = fees[_stablecoin]; fees[_stablecoin] = _fee; if (oldFee != _fee) emit FeeChanged(_stablecoin, oldFee, _fee); } /** @notice Remove the fee for burning CarbonDollar into a particular kind of stablecoin. @param _stablecoin Address of stablecoin. */ function removeFee(address _stablecoin) public onlyOwner { uint256 oldFee = fees[_stablecoin]; fees[_stablecoin] = 0; if (oldFee != 0) emit FeeRemoved(_stablecoin, oldFee); } /** @notice Add a token to the whitelist. @param _stablecoin Address of the new stablecoin. */ function addStablecoin(address _stablecoin) public onlyOwner { whitelist[_stablecoin] = true; emit StablecoinAdded(_stablecoin); } /** @notice Removes a token from the whitelist. @param _stablecoin Address of the ex-stablecoin. */ function removeStablecoin(address _stablecoin) public onlyOwner { whitelist[_stablecoin] = false; emit StablecoinRemoved(_stablecoin); } /** * @notice Compute the fee that will be charged on a "burn" operation. * @param _amount The amount that will be traded. * @param _stablecoin The stablecoin whose fee will be used. */ function computeStablecoinFee(uint256 _amount, address _stablecoin) public view returns (uint256) { uint256 fee = fees[_stablecoin]; return computeFee(_amount, fee); } /** * @notice Compute the fee that will be charged on a "burn" operation. * @param _amount The amount that will be traded. * @param _fee The fee that will be charged, in tenths of a percent. */ function computeFee(uint256 _amount, uint256 _fee) public pure returns (uint256) { return _amount.mul(_fee).div(1000); } } /** * Utility library of inline functions on addresses */ library AddressUtils { /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param addr address to check * @return whether the target address is a contract */ function isContract(address addr) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solium-disable-next-line security/no-inline-assembly assembly { size := extcodesize(addr) } return size > 0; } } /** * @title PermissionedTokenStorage * @notice a PermissionedTokenStorage is constructed by setting Regulator, BalanceSheet, and AllowanceSheet locations. * Once the storages are set, they cannot be changed. */ contract PermissionedTokenStorage is Ownable { using SafeMath for uint256; /** Storage */ mapping (address => mapping (address => uint256)) public allowances; mapping (address => uint256) public balances; uint256 public totalSupply; function addAllowance(address _tokenHolder, address _spender, uint256 _value) public onlyOwner { allowances[_tokenHolder][_spender] = allowances[_tokenHolder][_spender].add(_value); } function subAllowance(address _tokenHolder, address _spender, uint256 _value) public onlyOwner { allowances[_tokenHolder][_spender] = allowances[_tokenHolder][_spender].sub(_value); } function setAllowance(address _tokenHolder, address _spender, uint256 _value) public onlyOwner { allowances[_tokenHolder][_spender] = _value; } function addBalance(address _addr, uint256 _value) public onlyOwner { balances[_addr] = balances[_addr].add(_value); } function subBalance(address _addr, uint256 _value) public onlyOwner { balances[_addr] = balances[_addr].sub(_value); } function setBalance(address _addr, uint256 _value) public onlyOwner { balances[_addr] = _value; } function addTotalSupply(uint256 _value) public onlyOwner { totalSupply = totalSupply.add(_value); } function subTotalSupply(uint256 _value) public onlyOwner { totalSupply = totalSupply.sub(_value); } function setTotalSupply(uint256 _value) public onlyOwner { totalSupply = _value; } } /** * @title Proxy * @dev Implements delegation of calls to other contracts, with proper * forwarding of return values and bubbling of failures. * It defines a fallback function that delegates all calls to the address * returned by the abstract _implementation() internal function. */ contract Proxy { /** * @dev Fallback function. * Implemented entirely in `_fallback`. */ function () payable external { _fallback(); } /** * @return The Address of the implementation. */ function _implementation() internal view returns (address); /** * @dev Delegates execution to an implementation contract. * This is a low level function that doesn't return to its internal call site. * It will return to the external caller whatever the implementation returns. * @param implementation Address to delegate. */ function _delegate(address implementation) internal { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize) } default { return(0, returndatasize) } } } /** * @dev Function that is run as the first thing in the fallback function. * Can be redefined in derived contracts to add functionality. * Redefinitions must call super._willFallback(). */ function _willFallback() internal { } /** * @dev fallback implementation. * Extracted to enable manual triggering. */ function _fallback() internal { _willFallback(); _delegate(_implementation()); } } /** * Utility library of inline functions on addresses */ // library AddressUtils { // /** // * Returns whether the target address is a contract // * @dev This function will return false if invoked during the constructor of a contract, // * as the code is not actually created until after the constructor finishes. // * @param addr address to check // * @return whether the target address is a contract // */ // function isContract(address addr) internal view returns (bool) { // uint256 size; // // XXX Currently there is no better way to check if there is a contract in an address // // than to check the size of the code at that address. // // See https://ethereum.stackexchange.com/a/14016/36603 // // for more details about how this works. // // TODO Check this again before the Serenity release, because all addresses will be // // contracts then. // // solium-disable-next-line security/no-inline-assembly // assembly { size := extcodesize(addr) } // return size > 0; // } // } /** * @title UpgradeabilityProxy * @dev This contract implements a proxy that allows to change the * implementation address to which it will delegate. * Such a change is called an implementation upgrade. */ contract UpgradeabilityProxy is Proxy { /** * @dev Emitted when the implementation is upgraded. * @param implementation Address of the new implementation. */ event Upgraded(address implementation); /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "org.zeppelinos.proxy.implementation", and is * validated in the constructor. */ bytes32 private constant IMPLEMENTATION_SLOT = 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3; /** * @dev Contract constructor. * @param _implementation Address of the initial implementation. */ constructor(address _implementation) public { assert(IMPLEMENTATION_SLOT == keccak256("org.zeppelinos.proxy.implementation")); _setImplementation(_implementation); } /** * @dev Returns the current implementation. * @return Address of the current implementation */ function _implementation() internal view returns (address impl) { bytes32 slot = IMPLEMENTATION_SLOT; assembly { impl := sload(slot) } } /** * @dev Upgrades the proxy to a new implementation. * @param newImplementation Address of the new implementation. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Sets the implementation address of the proxy. * @param newImplementation Address of the new implementation. */ function _setImplementation(address newImplementation) private { require(AddressUtils.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address"); bytes32 slot = IMPLEMENTATION_SLOT; assembly { sstore(slot, newImplementation) } } } /** * * @dev Stores permissions and validators and provides setter and getter methods. * Permissions determine which methods users have access to call. Validators * are able to mutate permissions at the Regulator level. * */ contract RegulatorStorage is Ownable { /** Structs */ /* Contains metadata about a permission to execute a particular method signature. */ struct Permission { string name; // A one-word description for the permission. e.g. "canMint" string description; // A longer description for the permission. e.g. "Allows user to mint tokens." string contract_name; // e.g. "PermissionedToken" bool active; // Permissions can be turned on or off by regulator } /** Constants: stores method signatures. These are potential permissions that a user can have, and each permission gives the user the ability to call the associated PermissionedToken method signature */ bytes4 public constant MINT_SIG = bytes4(keccak256("mint(address,uint256)")); bytes4 public constant MINT_CUSD_SIG = bytes4(keccak256("mintCUSD(address,uint256)")); bytes4 public constant CONVERT_WT_SIG = bytes4(keccak256("convertWT(uint256)")); bytes4 public constant BURN_SIG = bytes4(keccak256("burn(uint256)")); bytes4 public constant CONVERT_CARBON_DOLLAR_SIG = bytes4(keccak256("convertCarbonDollar(address,uint256)")); bytes4 public constant BURN_CARBON_DOLLAR_SIG = bytes4(keccak256("burnCarbonDollar(address,uint256)")); bytes4 public constant DESTROY_BLACKLISTED_TOKENS_SIG = bytes4(keccak256("destroyBlacklistedTokens(address,uint256)")); bytes4 public constant APPROVE_BLACKLISTED_ADDRESS_SPENDER_SIG = bytes4(keccak256("approveBlacklistedAddressSpender(address)")); bytes4 public constant BLACKLISTED_SIG = bytes4(keccak256("blacklisted()")); /** Mappings */ /* each method signature maps to a Permission */ mapping (bytes4 => Permission) public permissions; /* list of validators, either active or inactive */ mapping (address => bool) public validators; /* each user can be given access to a given method signature */ mapping (address => mapping (bytes4 => bool)) public userPermissions; /** Events */ event PermissionAdded(bytes4 methodsignature); event PermissionRemoved(bytes4 methodsignature); event ValidatorAdded(address indexed validator); event ValidatorRemoved(address indexed validator); /** Modifiers */ /** * @notice Throws if called by any account that does not have access to set attributes */ modifier onlyValidator() { require (isValidator(msg.sender), "Sender must be validator"); _; } /** * @notice Sets a permission within the list of permissions. * @param _methodsignature Signature of the method that this permission controls. * @param _permissionName A "slug" name for this permission (e.g. "canMint"). * @param _permissionDescription A lengthier description for this permission (e.g. "Allows user to mint tokens"). * @param _contractName Name of the contract that the method belongs to. */ function addPermission( bytes4 _methodsignature, string _permissionName, string _permissionDescription, string _contractName) public onlyValidator { Permission memory p = Permission(_permissionName, _permissionDescription, _contractName, true); permissions[_methodsignature] = p; emit PermissionAdded(_methodsignature); } /** * @notice Removes a permission the list of permissions. * @param _methodsignature Signature of the method that this permission controls. */ function removePermission(bytes4 _methodsignature) public onlyValidator { permissions[_methodsignature].active = false; emit PermissionRemoved(_methodsignature); } /** * @notice Sets a permission in the list of permissions that a user has. * @param _methodsignature Signature of the method that this permission controls. */ function setUserPermission(address _who, bytes4 _methodsignature) public onlyValidator { require(permissions[_methodsignature].active, "Permission being set must be for a valid method signature"); userPermissions[_who][_methodsignature] = true; } /** * @notice Removes a permission from the list of permissions that a user has. * @param _methodsignature Signature of the method that this permission controls. */ function removeUserPermission(address _who, bytes4 _methodsignature) public onlyValidator { require(permissions[_methodsignature].active, "Permission being removed must be for a valid method signature"); userPermissions[_who][_methodsignature] = false; } /** * @notice add a Validator * @param _validator Address of validator to add */ function addValidator(address _validator) public onlyOwner { validators[_validator] = true; emit ValidatorAdded(_validator); } /** * @notice remove a Validator * @param _validator Address of validator to remove */ function removeValidator(address _validator) public onlyOwner { validators[_validator] = false; emit ValidatorRemoved(_validator); } /** * @notice does validator exist? * @return true if yes, false if no **/ function isValidator(address _validator) public view returns (bool) { return validators[_validator]; } /** * @notice does permission exist? * @return true if yes, false if no **/ function isPermission(bytes4 _methodsignature) public view returns (bool) { return permissions[_methodsignature].active; } /** * @notice get Permission structure * @param _methodsignature request to retrieve the Permission struct for this methodsignature * @return Permission **/ function getPermission(bytes4 _methodsignature) public view returns (string name, string description, string contract_name, bool active) { return (permissions[_methodsignature].name, permissions[_methodsignature].description, permissions[_methodsignature].contract_name, permissions[_methodsignature].active); } /** * @notice does permission exist? * @return true if yes, false if no **/ function hasUserPermission(address _who, bytes4 _methodsignature) public view returns (bool) { return userPermissions[_who][_methodsignature]; } } /** * @title Regulator * @dev Regulator can be configured to meet relevant securities regulations, KYC policies * AML requirements, tax laws, and more. The Regulator ensures that the PermissionedToken * makes compliant transfers possible. Contains the userPermissions necessary * for regulatory compliance. * */ contract Regulator is RegulatorStorage { /** Modifiers */ /** * @notice Throws if called by any account that does not have access to set attributes */ modifier onlyValidator() { require (isValidator(msg.sender), "Sender must be validator"); _; } /** Events */ event LogWhitelistedUser(address indexed who); event LogBlacklistedUser(address indexed who); event LogNonlistedUser(address indexed who); event LogSetMinter(address indexed who); event LogRemovedMinter(address indexed who); event LogSetBlacklistDestroyer(address indexed who); event LogRemovedBlacklistDestroyer(address indexed who); event LogSetBlacklistSpender(address indexed who); event LogRemovedBlacklistSpender(address indexed who); /** * @notice Sets the necessary permissions for a user to mint tokens. * @param _who The address of the account that we are setting permissions for. */ function setMinter(address _who) public onlyValidator { _setMinter(_who); } /** * @notice Removes the necessary permissions for a user to mint tokens. * @param _who The address of the account that we are removing permissions for. */ function removeMinter(address _who) public onlyValidator { _removeMinter(_who); } /** * @notice Sets the necessary permissions for a user to spend tokens from a blacklisted account. * @param _who The address of the account that we are setting permissions for. */ function setBlacklistSpender(address _who) public onlyValidator { require(isPermission(APPROVE_BLACKLISTED_ADDRESS_SPENDER_SIG), "Blacklist spending not supported by token"); setUserPermission(_who, APPROVE_BLACKLISTED_ADDRESS_SPENDER_SIG); emit LogSetBlacklistSpender(_who); } /** * @notice Removes the necessary permissions for a user to spend tokens from a blacklisted account. * @param _who The address of the account that we are removing permissions for. */ function removeBlacklistSpender(address _who) public onlyValidator { require(isPermission(APPROVE_BLACKLISTED_ADDRESS_SPENDER_SIG), "Blacklist spending not supported by token"); removeUserPermission(_who, APPROVE_BLACKLISTED_ADDRESS_SPENDER_SIG); emit LogRemovedBlacklistSpender(_who); } /** * @notice Sets the necessary permissions for a user to destroy tokens from a blacklisted account. * @param _who The address of the account that we are setting permissions for. */ function setBlacklistDestroyer(address _who) public onlyValidator { require(isPermission(DESTROY_BLACKLISTED_TOKENS_SIG), "Blacklist token destruction not supported by token"); setUserPermission(_who, DESTROY_BLACKLISTED_TOKENS_SIG); emit LogSetBlacklistDestroyer(_who); } /** * @notice Removes the necessary permissions for a user to destroy tokens from a blacklisted account. * @param _who The address of the account that we are removing permissions for. */ function removeBlacklistDestroyer(address _who) public onlyValidator { require(isPermission(DESTROY_BLACKLISTED_TOKENS_SIG), "Blacklist token destruction not supported by token"); removeUserPermission(_who, DESTROY_BLACKLISTED_TOKENS_SIG); emit LogRemovedBlacklistDestroyer(_who); } /** * @notice Sets the necessary permissions for a "whitelisted" user. * @param _who The address of the account that we are setting permissions for. */ function setWhitelistedUser(address _who) public onlyValidator { _setWhitelistedUser(_who); } /** * @notice Sets the necessary permissions for a "blacklisted" user. A blacklisted user has their accounts * frozen; they cannot transfer, burn, or withdraw any tokens. * @param _who The address of the account that we are setting permissions for. */ function setBlacklistedUser(address _who) public onlyValidator { _setBlacklistedUser(_who); } /** * @notice Sets the necessary permissions for a "nonlisted" user. Nonlisted users can trade tokens, * but cannot burn them (and therefore cannot convert them into fiat.) * @param _who The address of the account that we are setting permissions for. */ function setNonlistedUser(address _who) public onlyValidator { _setNonlistedUser(_who); } /** Returns whether or not a user is whitelisted. * @param _who The address of the account in question. * @return `true` if the user is whitelisted, `false` otherwise. */ function isWhitelistedUser(address _who) public view returns (bool) { return (hasUserPermission(_who, BURN_SIG) && !hasUserPermission(_who, BLACKLISTED_SIG)); } /** Returns whether or not a user is blacklisted. * @param _who The address of the account in question. * @return `true` if the user is blacklisted, `false` otherwise. */ function isBlacklistedUser(address _who) public view returns (bool) { return (!hasUserPermission(_who, BURN_SIG) && hasUserPermission(_who, BLACKLISTED_SIG)); } /** Returns whether or not a user is nonlisted. * @param _who The address of the account in question. * @return `true` if the user is nonlisted, `false` otherwise. */ function isNonlistedUser(address _who) public view returns (bool) { return (!hasUserPermission(_who, BURN_SIG) && !hasUserPermission(_who, BLACKLISTED_SIG)); } /** Returns whether or not a user is a blacklist spender. * @param _who The address of the account in question. * @return `true` if the user is a blacklist spender, `false` otherwise. */ function isBlacklistSpender(address _who) public view returns (bool) { return hasUserPermission(_who, APPROVE_BLACKLISTED_ADDRESS_SPENDER_SIG); } /** Returns whether or not a user is a blacklist destroyer. * @param _who The address of the account in question. * @return `true` if the user is a blacklist destroyer, `false` otherwise. */ function isBlacklistDestroyer(address _who) public view returns (bool) { return hasUserPermission(_who, DESTROY_BLACKLISTED_TOKENS_SIG); } /** Returns whether or not a user is a minter. * @param _who The address of the account in question. * @return `true` if the user is a minter, `false` otherwise. */ function isMinter(address _who) public view returns (bool) { return hasUserPermission(_who, MINT_SIG); } /** Internal Functions **/ function _setMinter(address _who) internal { require(isPermission(MINT_SIG), "Minting not supported by token"); setUserPermission(_who, MINT_SIG); emit LogSetMinter(_who); } function _removeMinter(address _who) internal { require(isPermission(MINT_SIG), "Minting not supported by token"); removeUserPermission(_who, MINT_SIG); emit LogRemovedMinter(_who); } function _setNonlistedUser(address _who) internal { require(isPermission(BURN_SIG), "Burn method not supported by token"); require(isPermission(BLACKLISTED_SIG), "Self-destruct method not supported by token"); removeUserPermission(_who, BURN_SIG); removeUserPermission(_who, BLACKLISTED_SIG); emit LogNonlistedUser(_who); } function _setBlacklistedUser(address _who) internal { require(isPermission(BURN_SIG), "Burn method not supported by token"); require(isPermission(BLACKLISTED_SIG), "Self-destruct method not supported by token"); removeUserPermission(_who, BURN_SIG); setUserPermission(_who, BLACKLISTED_SIG); emit LogBlacklistedUser(_who); } function _setWhitelistedUser(address _who) internal { require(isPermission(BURN_SIG), "Burn method not supported by token"); require(isPermission(BLACKLISTED_SIG), "Self-destruct method not supported by token"); setUserPermission(_who, BURN_SIG); removeUserPermission(_who, BLACKLISTED_SIG); emit LogWhitelistedUser(_who); } } /** * @title PermissionedTokenProxy * @notice A proxy contract that serves the latest implementation of PermissionedToken. */ contract PermissionedTokenProxy is UpgradeabilityProxy, Ownable { PermissionedTokenStorage public tokenStorage; Regulator public regulator; // Events event ChangedRegulator(address indexed oldRegulator, address indexed newRegulator ); /** * @dev create a new PermissionedToken as a proxy contract * with a brand new data storage **/ constructor(address _implementation, address _regulator) UpgradeabilityProxy(_implementation) public { regulator = Regulator(_regulator); tokenStorage = new PermissionedTokenStorage(); } /** * @dev Upgrade the backing implementation of the proxy. * Only the admin can call this function. * @param newImplementation Address of the new implementation. */ function upgradeTo(address newImplementation) public onlyOwner { _upgradeTo(newImplementation); } /** * @return The address of the implementation. */ function implementation() public view returns (address) { return _implementation(); } } /** * @title CarbonDollarRegulator * @dev CarbonDollarRegulator is a type of Regulator that modifies its definitions of * what constitutes a "whitelisted/nonlisted/blacklisted" user. A CarbonDollar * provides a user the additional ability to convert from CUSD into a whtielisted stablecoin * */ contract CarbonDollarRegulator is Regulator { // Getters function isWhitelistedUser(address _who) public view returns(bool) { return (hasUserPermission(_who, CONVERT_CARBON_DOLLAR_SIG) && hasUserPermission(_who, BURN_CARBON_DOLLAR_SIG) && !hasUserPermission(_who, BLACKLISTED_SIG)); } function isBlacklistedUser(address _who) public view returns(bool) { return (!hasUserPermission(_who, CONVERT_CARBON_DOLLAR_SIG) && !hasUserPermission(_who, BURN_CARBON_DOLLAR_SIG) && hasUserPermission(_who, BLACKLISTED_SIG)); } function isNonlistedUser(address _who) public view returns(bool) { return (!hasUserPermission(_who, CONVERT_CARBON_DOLLAR_SIG) && !hasUserPermission(_who, BURN_CARBON_DOLLAR_SIG) && !hasUserPermission(_who, BLACKLISTED_SIG)); } /** Internal functions **/ // Setters: CarbonDollarRegulator overrides the definitions of whitelisted, nonlisted, and blacklisted setUserPermission // CarbonDollar whitelisted users burn CUSD into a WhitelistedToken. Unlike PermissionedToken // whitelisted users, CarbonDollar whitelisted users cannot burn ordinary CUSD without converting into WT function _setWhitelistedUser(address _who) internal { require(isPermission(CONVERT_CARBON_DOLLAR_SIG), "Converting CUSD not supported"); require(isPermission(BURN_CARBON_DOLLAR_SIG), "Burning CUSD not supported"); require(isPermission(BLACKLISTED_SIG), "Blacklisting not supported"); setUserPermission(_who, CONVERT_CARBON_DOLLAR_SIG); setUserPermission(_who, BURN_CARBON_DOLLAR_SIG); removeUserPermission(_who, BLACKLISTED_SIG); emit LogWhitelistedUser(_who); } function _setBlacklistedUser(address _who) internal { require(isPermission(CONVERT_CARBON_DOLLAR_SIG), "Converting CUSD not supported"); require(isPermission(BURN_CARBON_DOLLAR_SIG), "Burning CUSD not supported"); require(isPermission(BLACKLISTED_SIG), "Blacklisting not supported"); removeUserPermission(_who, CONVERT_CARBON_DOLLAR_SIG); removeUserPermission(_who, BURN_CARBON_DOLLAR_SIG); setUserPermission(_who, BLACKLISTED_SIG); emit LogBlacklistedUser(_who); } function _setNonlistedUser(address _who) internal { require(isPermission(CONVERT_CARBON_DOLLAR_SIG), "Converting CUSD not supported"); require(isPermission(BURN_CARBON_DOLLAR_SIG), "Burning CUSD not supported"); require(isPermission(BLACKLISTED_SIG), "Blacklisting not supported"); removeUserPermission(_who, CONVERT_CARBON_DOLLAR_SIG); removeUserPermission(_who, BURN_CARBON_DOLLAR_SIG); removeUserPermission(_who, BLACKLISTED_SIG); emit LogNonlistedUser(_who); } } /** * @title CarbonDollarProxy * @notice This contract will be the public facing CarbonUSD. All calls to the CarbonUSD contract will * be routed through this proxy, since this proxy contract is the owner of the * storage contracts. */ contract CarbonDollarProxy is PermissionedTokenProxy { CarbonDollarStorage public tokenStorage_CD; /** CONSTRUCTOR * @dev Passes along arguments to base class. */ constructor(address _implementation, address _regulator) public PermissionedTokenProxy(_implementation, _regulator) { // base class override regulator = CarbonDollarRegulator(_regulator); tokenStorage_CD = new CarbonDollarStorage(); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[{"name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenStorage_CD","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenStorage","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"regulator","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pendingOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_implementation","type":"address"},{"name":"_regulator","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"oldRegulator","type":"address"},{"indexed":true,"name":"newRegulator","type":"address"}],"name":"ChangedRegulator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"implementation","type":"address"}],"name":"Upgraded","type":"event"}]
Contract Creation Code
608060405234801561001057600080fd5b5060405160408061154a83398101604081815282516020938401517f6f72672e7a657070656c696e6f732e70726f78792e696d706c656d656e74617484527f696f6e00000000000000000000000000000000000000000000000000000000009484019490945290519182900360230190912090919082908290829060008051602061152a833981519152146100a157fe5b6100b381640100000000610189810204565b506000805433600160a060020a031991821617909155600180548216905560038054909116600160a060020a0383161790556100ed61024f565b604051809103906000f080158015610109573d6000803e3d6000fd5b5060028054600160a060020a0319908116600160a060020a03938416179091556003805490911691851691909117905550610144905061025f565b604051809103906000f080158015610160573d6000803e3d6000fd5b5060048054600160a060020a031916600160a060020a03929092169190911790555061026f9050565b60006101a18264010000000061046161024782021704565b151561023457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f60448201527f6e20746f2061206e6f6e2d636f6e747261637420616464726573730000000000606482015290519081900360840190fd5b5060008051602061152a83398151915255565b6000903b1190565b6040516107188061071383390190565b6040516106ff80610e2b83390190565b6104958061027e6000396000f3006080604052600436106100985763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633659cfe681146100a25780634e71e0c8146100c35780635c60da1b146100d85780638da5cb5b146101095780639d36b5c41461011e578063b199efb514610133578063dd8fee1414610148578063e30c39781461015d578063f2fde38b14610172575b6100a0610193565b005b3480156100ae57600080fd5b506100a0600160a060020a03600435166101ad565b3480156100cf57600080fd5b506100a06101d0565b3480156100e457600080fd5b506100ed610258565b60408051600160a060020a039092168252519081900360200190f35b34801561011557600080fd5b506100ed610267565b34801561012a57600080fd5b506100ed610276565b34801561013f57600080fd5b506100ed610285565b34801561015457600080fd5b506100ed610294565b34801561016957600080fd5b506100ed6102a3565b34801561017e57600080fd5b506100a0600160a060020a03600435166102b2565b61019b6101ab565b6101ab6101a661030d565b610332565b565b600054600160a060020a031633146101c457600080fd5b6101cd81610356565b50565b600154600160a060020a031633146101e757600080fd5b60015460008054604051600160a060020a0393841693909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600180546000805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155169055565b600061026261030d565b905090565b600054600160a060020a031681565b600454600160a060020a031681565b600254600160a060020a031681565b600354600160a060020a031681565b600154600160a060020a031681565b600054600160a060020a031633146102c957600080fd5b600160a060020a03811615156102de57600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e808015610351573d6000f35b3d6000fd5b61035f8161039e565b60408051600160a060020a038316815290517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9181900360200190a150565b60006103a982610461565b151561043c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f60448201527f6e20746f2061206e6f6e2d636f6e747261637420616464726573730000000000606482015290519081900360840190fd5b507f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c355565b6000903b11905600a165627a7a7230582039a474902e3e83e41aade00d740ae2d895fcbbf885390cab31506b94c38e00770029608060405260008054600160a060020a031990811633179091556001805490911690556106e7806100316000396000f3006080604052600436106100e55763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166318160ddd81146100ea57806321e5383a1461011157806327e235e3146101375780634e71e0c81461015857806355b6ed5c1461016d5780635fd72d161461019457806382838c76146101be5780638da5cb5b146101d657806397d88cd214610207578063cf8eeb7e14610231578063da46098c14610255578063e30443bc1461027f578063e30c3978146102a3578063e468688e146102b8578063f2fde38b146102d0578063f7ea7a3d146102f1575b600080fd5b3480156100f657600080fd5b506100ff610309565b60408051918252519081900360200190f35b34801561011d57600080fd5b50610135600160a060020a036004351660243561030f565b005b34801561014357600080fd5b506100ff600160a060020a036004351661036f565b34801561016457600080fd5b50610135610381565b34801561017957600080fd5b506100ff600160a060020a0360043581169060243516610409565b3480156101a057600080fd5b50610135600160a060020a0360043581169060243516604435610426565b3480156101ca57600080fd5b506101356004356104a4565b3480156101e257600080fd5b506101eb6104d4565b60408051600160a060020a039092168252519081900360200190f35b34801561021357600080fd5b50610135600160a060020a03600435811690602435166044356104e3565b34801561023d57600080fd5b50610135600160a060020a0360043516602435610530565b34801561026157600080fd5b50610135600160a060020a0360043581169060243516604435610570565b34801561028b57600080fd5b50610135600160a060020a03600435166024356105b3565b3480156102af57600080fd5b506101eb6105e6565b3480156102c457600080fd5b506101356004356105f5565b3480156102dc57600080fd5b50610135600160a060020a036004351661061f565b3480156102fd57600080fd5b5061013560043561067a565b60045481565b600054600160a060020a0316331461032657600080fd5b600160a060020a03821660009081526003602052604090205461034f908263ffffffff61069616565b600160a060020a0390921660009081526003602052604090209190915550565b60036020526000908152604090205481565b600154600160a060020a0316331461039857600080fd5b60015460008054604051600160a060020a0393841693909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600180546000805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155169055565b600260209081526000928352604080842090915290825290205481565b600054600160a060020a0316331461043d57600080fd5b600160a060020a03808416600090815260026020908152604080832093861683529290522054610473908263ffffffff61069616565b600160a060020a03938416600090815260026020908152604080832095909616825293909352929091209190915550565b600054600160a060020a031633146104bb57600080fd5b6004546104ce908263ffffffff6106a916565b60045550565b600054600160a060020a031681565b600054600160a060020a031633146104fa57600080fd5b600160a060020a03808416600090815260026020908152604080832093861683529290522054610473908263ffffffff6106a916565b600054600160a060020a0316331461054757600080fd5b600160a060020a03821660009081526003602052604090205461034f908263ffffffff6106a916565b600054600160a060020a0316331461058757600080fd5b600160a060020a0392831660009081526002602090815260408083209490951682529290925291902055565b600054600160a060020a031633146105ca57600080fd5b600160a060020a03909116600090815260036020526040902055565b600154600160a060020a031681565b600054600160a060020a0316331461060c57600080fd5b6004546104ce908263ffffffff61069616565b600054600160a060020a0316331461063657600080fd5b600160a060020a038116151561064b57600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600054600160a060020a0316331461069157600080fd5b600455565b818101828110156106a357fe5b92915050565b6000828211156106b557fe5b509003905600a165627a7a7230582030b4709879e7ed489adc4852a3a25d79e97fbf852402b8daeb0367f2a4835d400029608060405260008054600160a060020a031990811633179091556001805490911690556106ce806100316000396000f3006080604052600436106100cf5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630418945a81146100d4578063166e55d9146100f75780632ff284c21461012d5780633b947d2b146101485780634e71e0c8146101695780635a6c72d01461017e5780636ad26611146101935780638da5cb5b146101b45780639b19251a146101e5578063c93a6c841461021a578063e30c397814610232578063e55156b514610247578063f2fde38b1461026b578063faaebd211461028c575b600080fd5b3480156100e057600080fd5b506100f5600160a060020a03600435166102ad565b005b34801561010357600080fd5b5061011b600435600160a060020a0360243516610310565b60408051918252519081900360200190f35b34801561013957600080fd5b5061011b60043560243561033b565b34801561015457600080fd5b506100f5600160a060020a0360043516610368565b34801561017557600080fd5b506100f56103c8565b34801561018a57600080fd5b5061011b610450565b34801561019f57600080fd5b506100f5600160a060020a0360043516610456565b3480156101c057600080fd5b506101c96104d6565b60408051600160a060020a039092168252519081900360200190f35b3480156101f157600080fd5b50610206600160a060020a03600435166104e5565b604080519115158252519081900360200190f35b34801561022657600080fd5b506100f56004356104fa565b34801561023e57600080fd5b506101c9610561565b34801561025357600080fd5b506100f5600160a060020a0360043516602435610570565b34801561027757600080fd5b506100f5600160a060020a03600435166105f7565b34801561029857600080fd5b5061011b600160a060020a0360043516610652565b600054600160a060020a031633146102c457600080fd5b600160a060020a038116600081815260046020526040808220805460ff19166001179055517f3db297c09c19972ba6a701ff373ab97e21ff1e4992e863c7abe44e9b2fed08479190a250565b600160a060020a038116600090815260026020526040812054610333848261033b565b949350505050565b600061035f6103e8610353858563ffffffff61066416565b9063ffffffff61068d16565b90505b92915050565b600054600160a060020a0316331461037f57600080fd5b600160a060020a038116600081815260046020526040808220805460ff19169055517f3302a1b37f04242bb55603f5449e7ecd690a35eef08ba1353c48c20e2aae9cda9190a250565b600154600160a060020a031633146103df57600080fd5b60015460008054604051600160a060020a0393841693909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600180546000805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155169055565b60035481565b60008054600160a060020a0316331461046e57600080fd5b50600160a060020a0381166000908152600260205260408120805491905580156104d257604080518281529051600160a060020a038416917fe4ca060d5956a829454e1f8734d008a552f7c9a701ba632810443acc98435c68919081900360200190a25b5050565b600054600160a060020a031681565b60046020526000908152604090205460ff1681565b60008054600160a060020a0316331461051257600080fd5b5060038054908290558181146104d257604080518281526020810184905281517f2faa036c952bde05f63e87e0c61278ffd974bfc128a2b0ef03fafdb57f5d5cea929181900390910190a15050565b600154600160a060020a031681565b60008054600160a060020a0316331461058857600080fd5b50600160a060020a03821660009081526002602052604090208054908290558181146105f25760408051828152602081018490528151600160a060020a038616927ff98c81ad0a5eb3551c3561de8dc9d1512e8680fb77425ea138ebfe9a9c0065ff928290030190a25b505050565b600054600160a060020a0316331461060e57600080fd5b600160a060020a038116151561062357600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b60026020526000908152604090205481565b600082151561067557506000610362565b5081810281838281151561068557fe5b041461036257fe5b6000818381151561069a57fe5b0493925050505600a165627a7a7230582021aabf8ad534ca47a098935ff1b5ac8b1266bc01fe831b9706073d746f0f958700297050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3000000000000000000000000e05b1e8463773a2368760bfff14c2bb20821d990000000000000000000000000be729d06dd2d7b2e953b40e234c62bd5f0204a12
Deployed Bytecode
0x6080604052600436106100985763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633659cfe681146100a25780634e71e0c8146100c35780635c60da1b146100d85780638da5cb5b146101095780639d36b5c41461011e578063b199efb514610133578063dd8fee1414610148578063e30c39781461015d578063f2fde38b14610172575b6100a0610193565b005b3480156100ae57600080fd5b506100a0600160a060020a03600435166101ad565b3480156100cf57600080fd5b506100a06101d0565b3480156100e457600080fd5b506100ed610258565b60408051600160a060020a039092168252519081900360200190f35b34801561011557600080fd5b506100ed610267565b34801561012a57600080fd5b506100ed610276565b34801561013f57600080fd5b506100ed610285565b34801561015457600080fd5b506100ed610294565b34801561016957600080fd5b506100ed6102a3565b34801561017e57600080fd5b506100a0600160a060020a03600435166102b2565b61019b6101ab565b6101ab6101a661030d565b610332565b565b600054600160a060020a031633146101c457600080fd5b6101cd81610356565b50565b600154600160a060020a031633146101e757600080fd5b60015460008054604051600160a060020a0393841693909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600180546000805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155169055565b600061026261030d565b905090565b600054600160a060020a031681565b600454600160a060020a031681565b600254600160a060020a031681565b600354600160a060020a031681565b600154600160a060020a031681565b600054600160a060020a031633146102c957600080fd5b600160a060020a03811615156102de57600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e808015610351573d6000f35b3d6000fd5b61035f8161039e565b60408051600160a060020a038316815290517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9181900360200190a150565b60006103a982610461565b151561043c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f60448201527f6e20746f2061206e6f6e2d636f6e747261637420616464726573730000000000606482015290519081900360840190fd5b507f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c355565b6000903b11905600a165627a7a7230582039a474902e3e83e41aade00d740ae2d895fcbbf885390cab31506b94c38e00770029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e05b1e8463773a2368760bfff14c2bb20821d990000000000000000000000000be729d06dd2d7b2e953b40e234c62bd5f0204a12
-----Decoded View---------------
Arg [0] : _implementation (address): 0xe05b1e8463773a2368760BfFf14c2BB20821D990
Arg [1] : _regulator (address): 0xBE729D06DD2D7B2e953b40E234c62Bd5F0204a12
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000e05b1e8463773a2368760bfff14c2bb20821d990
Arg [1] : 000000000000000000000000be729d06dd2d7b2e953b40e234c62bd5f0204a12
Swarm Source
bzzr://21aabf8ad534ca47a098935ff1b5ac8b1266bc01fe831b9706073d746f0f9587
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.