Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pragma solidity ^0.4.18;
- import "zeppelin-solidity/contracts/ownership/Claimable.sol";
- import "zeppelin-solidity/contracts/token/ERC20/DetailedERC20.sol";
- import "zeppelin-solidity/contracts/token/ERC20/MintableToken.sol";
- import "./mixins/ReissuableToken.sol";
- import "./RegulatorService/IRegulatorService.sol";
- import "./ServiceRegistry.sol";
- /// @notice An ERC-20 token that has the ability to check for trade validity
- contract RegulatedToken is ReissuableToken, DetailedERC20, MintableToken, Claimable {
- /**
- * @notice R-Token decimals setting (used when constructing DetailedERC20)
- */
- uint8 constant public RTOKEN_DECIMALS = 18;
- /**
- * @notice Triggered when regulator checks pass or fail
- */
- event LogCheckResponse(
- uint8 code,
- address indexed spender,
- address indexed from,
- address indexed to,
- uint256 value
- );
- /**
- * @notice Address of the `ServiceRegistry` that has the location of the
- * `RegulatorService` contract responsible for checking trade
- * permissions.
- */
- ServiceRegistry public registry;
- /**
- * @notice Constructor
- *
- * @param _registry Address of `ServiceRegistry` contract
- * @param _name Name of the token: See DetailedERC20
- * @param _symbol Symbol of the token: See DetailedERC20
- */
- function RegulatedToken(
- ServiceRegistry _registry,
- string _name,
- string _symbol
- )
- public
- DetailedERC20(_name, _symbol, RTOKEN_DECIMALS)
- {
- require(_registry != address(0), "Registry address cannot be 0");
- registry = _registry;
- }
- function mint(
- address _to,
- uint256 _amount
- )
- public
- onlyOwner
- canMint
- returns (bool)
- {
- bool mintSuccess = super.mint(_to, _amount);
- if (mintSuccess) {
- _onMintSuccess(_to, _amount);
- }
- return mintSuccess;
- }
- /**
- * @notice ERC-20 overridden function that include logic to check for
- * trade validity.
- *
- * @dev Must pass `msg.sender` as `from` field to `_check()`
- *
- * @param _to The address of the receiver
- * @param _value The number of tokens to transfer
- *
- * @return `true` if successful and `false` if unsuccessful
- */
- function transfer(address _to, uint256 _value) public returns (bool) {
- if (_check(msg.sender, _to, _value)) {
- bool transferSuccess = super.transfer(_to, _value);
- if (transferSuccess) {
- _onTransferSuccess(msg.sender, msg.sender, _to, _value);
- }
- return transferSuccess;
- } else {
- return false;
- }
- }
- /**
- * @notice ERC-20 overridden function that include logic to check for
- * trade validity.
- *
- * @param _from The address of the sender
- * @param _to The address of the receiver
- * @param _value The number of tokens to transfer
- *
- * @return `true` if successful and `false` if unsuccessful
- */
- function transferFrom(
- address _from,
- address _to,
- uint256 _value
- ) public returns (bool) {
- if (_check(_from, _to, _value)) {
- bool transferSuccess = super.transferFrom(_from, _to, _value);
- if (transferSuccess) {
- _onTransferSuccess(msg.sender, _from, _to, _value);
- }
- return transferSuccess;
- } else {
- return false;
- }
- }
- /**
- * @dev Modify `reissuer()` to call `_onTransferSuccess` if it returns true.
- */
- function reissue(address _from, address _to, uint256 _amount)
- public
- onlyReissuer
- returns (bool)
- {
- bool reissuerSuccess = super.reissue(_from, _to, _amount);
- if (reissuerSuccess) {
- _onTransferSuccess(msg.sender, _from, _to, _amount);
- }
- return reissuerSuccess;
- }
- /**
- * @notice Performs the regulator check
- *
- * @dev This method raises a CheckStatus event indicating success or
- * failure of the check
- *
- * @param _from The address of the sender
- * @param _to The address of the receiver
- * @param _value The number of tokens to transfer
- *
- * @return `true` if the check was successful and `false` if unsuccessful
- */
- function _check(
- address _from,
- address _to,
- uint256 _value
- ) private returns (bool) {
- uint8 code = _service().check(this, msg.sender, _from, _to, _value);
- emit LogCheckResponse(code, msg.sender, _from, _to, _value);
- return code == 0;
- }
- /**
- * @notice Calls back to `RegulatedService` to handle successful mints
- *
- * @param _to The address of the receiver account
- * @param _amount The quantity of the token to trade
- */
- function _onMintSuccess(address _to, uint256 _amount) private {
- _service().onMintSuccess(_to, _amount);
- }
- /**
- * @notice Calls back to `RegulatedService` to handle successful transfers
- *
- * @param _spender The address of the spender of the token
- * @param _from The address of the sender account
- * @param _to The address of the receiver account
- * @param _value The quantity of the token to trade
- */
- function _onTransferSuccess(
- address _spender,
- address _from,
- address _to,
- uint256 _value
- ) private {
- _service().onTransferSuccess(_spender, _from, _to, _value);
- }
- /**
- * @notice Retreives the address of the `RegulatorService` that manages
- * this token.
- *
- * @dev This function *MUST NOT* memoize the `RegulatorService` address.
- * This would break the ability to upgrade the `RegulatorService`.
- *
- * @return The `RegulatorService` that manages this token.
- */
- function _service() constant public returns (IRegulatorService) {
- return IRegulatorService(registry.service());
- }
- }
Add Comment
Please, Sign In to add comment