TruUpgradeableToken

Title: TruUpgradeableToken
Description: Smart Contract derived from UpgradeableToken by Token Market with additional functionality for the TruReputationToken.
Author: Ian Bray, Tru Ltd
Solidity Version: 0.4.18
Relative Path: ./contracts/supporting/TruUpgradeableToken.sol
License: Apache 2 License
Current Version: 0.1.9
Original Source: UpgradeableToken

1. Imports & Dependencies

The following imports and dependencies exist for the TruUpgradeableToken Solidity Library:

Name Description
SafeMath Zeppelin Solidity Library to perform mathematics safely inside Solidity
StandardToken Zeppelin Solidity Smart Contract for a Standard ERC-20 Token
TruUpgradeableToken Library of helper functions surrounding the Solidity Address type
UpgradeAgent Token Market Smart Contract used to facilitate upgrading of tokens

2. Variables

The following variables exist for the TruUpgradeableToken Smart Contract:

Variable Type Vis Details
upgradeMaster address public Variable containing the address of the wallet designated as the Upgrade Master
upgradeAgent UpgradeAgent public Variable containing the UpgradeAgent Contract Instance
totalUpgraded uint256 public Variable to track the number of tokens that have been upgraded

3. Enums

The following enums exist for the TruUpgradeableToken Solidity Library:

Enum Description
UpgradeState Enum of the different states an UpgradeableToken can be in.

UpgradeState

The following enum states exist for the UpgradeState enum:

Enum States Detail
Unknown Token upgrade is in an Unknown State- fallback state not used
NotAllowed The child contract has not reached a condition where the upgrade can begin
WaitingForAgent Token allows upgrade, but an upgradeAgent has not been set
ReadyToUpgrade The upgradeAgent is set, but no tokens have been upgraded yet
Upgrading The upgradeAgent is set, and balance holders can upgrade their tokens

4. Events

The following events exist for the TruUpgradeableToken Solidity Library:

Name Description
Upgrade Event to notify when a token holder upgrades their tokens
UpgradeAgentSet Event to notify when an upgradeAgent is set
NewUpgradedAmount Event to notify the new total number of tokens that have been upgraded

Upgrade

Event Name: Upgrade
Description: Event to notify when a token holder upgrades their tokens

Usage

The Upgrade event has the following usage syntax and arguments:

  Argument Type Indexed? Details
1 from address Yes Source wallet that the older tokens are sent from
2 to address Yes Address of the destination for upgraded tokens which is hardcoded to the upgradeAgent who sends them back to the originating address
3 upgradeValue uint256 No Number of tokens to upgrade
Upgrade Usage Example
Upgrade(0x123456789abcdefghijklmnopqrstuvwxyz98765,
        0x123456789abcdefghijklmnopqrstuvwxyz01234,
        100);

UpgradeAgentSet

Event Name: UpgradeAgentSet
Description: Event to notify when an upgradeAgent is set

Usage

The UpgradeAgentSet event has the following usage syntax and arguments:

  Argument Type Indexed? Details
1 agent address Yes Address of new upgradeAgent
2 executor address Yes Address that executed the UpgradeAgentSet event
UpgradeAgentSet Usage Example
UpgradeAgentSet(0x123456789abcdefghijklmnopqrstuvwxyz98765,
                0x123456789abcdefghijklmnopqrstuvwxyz01234);

NewUpgradedAmount

Event Name: NewUpgradedAmount
Description: Event to notify when an upgradeAgent is set

Usage

The NewUpgradedAmount event has the following usage syntax and arguments:

  Argument Type Indexed? Details
1 originalBalance uint256 No Balance of Upgrade Tokens before
2 newBalance uint256 No Balance of Upgrade Tokens after
3 executor address Yes Address that executed the NewUpgradedAmount event
NewUpgradedAmount Usage Example
NewUpgradedAmount(50, 100);

5. Mappings

There are no mappings for the TruUpgradeableToken Smart Contract.

6. Modifiers

The following modifiers exist for the TruUpgradeableToken Smart Contract:

Name Description
onlyUpgradeMaster Modifier to check the Upgrade Master is executing this call

onlyUpgradeMaster

Modifier Name: onlyUpgradeMaster
Description: Modifier to check the Upgrade Master is executing this call

Code

The code for the onlyUpgradeMaster modifier is as follows:

onlyUpgradeMaster Code
modifier onlyUpgradeMaster() {
    require(msg.sender == upgradeMaster);
    _;
}

The onlyUpgradeMaster function performs the following:

  • Checks that the msg.sender matches the upgradeMaster variable

7. Functions

The following functions exist for the TruUpgradeableToken Smart Contract:

Name Description
TruUpgradeableToken Constructor Constructor for the TruUpgradeableToken Smart Contract
upgrade Function to upgrade tokens.
setUpgradeAgent Function to set the upgradeAgent variable
getUpgradeState Function to get the current UpgradeState for the token
setUpgradeMaster Function to change the upgradeMaster variable
canUpgrade Function to get whether the token can be upgraded

TruUpgradeableToken Constructor

Function Name: TruUpgradeableToken
Description: Constructor for the TruUpgradeableToken Smart Contract
Function Type: Constructor
Function Visibility: Public
Function Modifiers: N/A
Return Type: None
Return Details: N/A

Code

The code for the TruUpgradeableToken Constructor function is as follows:

TruUpgradeableToken Constructor Code
function TruUpgradeableToken(address _upgradeMaster) public {
    require(TruAddress.isValid(_upgradeMaster) == true);
    upgradeMaster = _upgradeMaster;
}

The TruUpgradeableToken Constructor function performs the following:

  • Checks the _upgradeMaster is a valid Ethereum address.
  • Sets the upgradeMaster variable to the _upgradeMaster argument value.

Usage

The TruUpgradeableToken Constructor function has the following usage syntax and arguments:

  Argument Type Details
1 _upgradeMaster address | Address to be set as the Upgrade Master
TruUpgradeableToken Constructor Usage Example
 TruUpgradeableToken(0x123456789abcdefghijklmnopqrstuvwxyz98765);

upgrade

Function Name: upgrade
Description: Function to upgrade tokens
Function Type: N/A
Function Visibility: Public
Function Modifiers: N/A
Return Type: None
Return Details: N/A

Code

The code for the upgrade function is as follows:

upgrade Code
function upgrade(uint256 value) public {
    UpgradeState state = getUpgradeState();
    require((state == UpgradeState.ReadyToUpgrade) || (state == UpgradeState.Upgrading));
    require(value > 0);
    require(balances[msg.sender] >= value);

    uint256 upgradedAmount = totalUpgraded.add(value);
    assert(upgradedAmount >= value);

    uint256 senderBalance = balances[msg.sender];
    uint256 newSenderBalance = senderBalance.sub(value);
    uint256 newTotalSupply = totalSupply.sub(value);
    balances[msg.sender] = newSenderBalance;
    totalSupply = newTotalSupply;
    NewUpgradedAmount(totalUpgraded, newTotalSupply);
    totalUpgraded = upgradedAmount;
    // Upgrade agent reissues the tokens
    upgradeAgent.upgradeFrom(msg.sender, value);
    Upgrade(msg.sender, upgradeAgent, value);
}

The upgrade function performs the following:

  • Checks the UpgradeState is either ReadyToUpgrade or Upgrading
  • Checks the upgrade amount value is greater than zero
  • Checks that the send has a balance of greater than or equal to the upgrade value
  • Adds the value to the totalUpgraded variable and checks that this new value is equal to or greater than the value to be upgraded.
  • Removes the value from the senders balance
  • Removes the value from the token’s totalSupply
  • Fires the NewUpgradedAmount event
  • Initiates the Upgrade Agent’s upgradeFrom functionality to deliver the value in upgraded tokens to the sender.
  • Fires the Upgrade event

Usage

The upgrade function has the following usage syntax and arguments:

  Argument Type Details
1 _value uint256 | Amount of tokens to be upgraded
upgrade Usage Example
 upgrade(100);

setUpgradeAgent

Function Name: setUpgradeAgent
Description: Function to set the upgradeAgent variable
Function Type: N/A
Function Visibility: Public
Function Modifiers: onlyUpgradeMaster
Return Type: None
Return Details: N/A

Code

The code for the setUpgradeAgent function is as follows:

setUpgradeAgent Code
function setUpgradeAgent(address _agent) public onlyUpgradeMaster {
    require(TruAddress.isValid(_agent) == true);
    require(canUpgrade());
    require(getUpgradeState() != UpgradeState.Upgrading);

    UpgradeAgent newUAgent = UpgradeAgent(_agent);

    require(newUAgent.isUpgradeAgent());
    require(newUAgent.originalSupply() == totalSupply);

    UpgradeAgentSet(upgradeAgent);

    upgradeAgent = newUAgent;
}

The setUpgradeAgent function performs the following:

  • Checks the _agent address is valid. If not, the function will throw.
  • Checks that the token can upgrade via the canUpgrade function. If not, the function will throw.
  • Checks that that UpgradeState is not Upgrading (and therefore in the middle of an upgrade). If not, the function will throw.
  • Checks that the specified Upgrade Agent contract is an Upgrade Agent. If not, the function will
    throw.
  • Checks that the Upgrade Agent’s original supply matches the current total supply of the token. If not, the function will throw.
  • Fires the UpgradeAgentSet event.
  • Sets the upgradeAgent variable.

Usage

The setUpgradeAgent function has the following usage syntax and arguments:

  Argument Type Details
1 _agent address | Address of the new Upgrade Agent
setUpgradeAgent Usage Example
setUpgradeAgent(0x123456789abcdefghijklmnopqrstuvwxyz98765);

getUpgradeState

Function Name: getUpgradeState
Description: Function to get the current UpgradeState of the token
Function Type: Constant
Function Visibility: Public
Function Modifiers: N/A
Return Type: UpgradeState
Return Details: Returns UpgradeState as a uint (0, 1, 2, 3 or 4)

Code

The code for the getUpgradeState function is as follows:

getUpgradeState Code
function getUpgradeState() public constant returns(UpgradeState) {
    if (!canUpgrade())
        return UpgradeState.NotAllowed;
    else if (TruAddress.isValid(upgradeAgent) == false)
        return UpgradeState.WaitingForAgent;
    else if (totalUpgraded == 0)
        return UpgradeState.ReadyToUpgrade;
    else
        return UpgradeState.Upgrading;
}

The getUpgradeState function performs the following:

  • the canUpgrade function to see if it is true. If it is false, returns NotAllowed UpgradeState
  • Checks the upgradeAgent address is valid and set. If it is not, returns WaitingForAgent UpgradeState
  • Checks that the totalUpgraded* is zero. If it is true, return ReadyToUpgrade UpgradeState
  • Else return Upgrading UpgradeState

Usage

The getUpgradeState function has the following usage syntax:

getUpgradeState Usage Example
getUpgradeState();

setUpgradeMaster

Function Name: setUpgradeMaster
Description: Function to change the upgradeMaster variable
Function Type: N/A
Function Visibility: Public
Function Modifiers: onlyUpgradeMaster
Return Type: UpgradeState
Return Details: Returns UpgradeState as a uint (0, 1, 2, 3 or 4)

Code

The code for the setUpgradeMaster function is as follows:

setUpgradeMaster Code
function setUpgradeMaster(address _master) public onlyUpgradeMaster {
    require(TruAddress.isValid(_master) == true);
    upgradeMaster = _master;
}

The setUpgradeMaster function performs the following:

  • Checks the _master argument is a valid Ethereum Address. If it is not, it will throw.
  • Sets the upgradeMaster variable to the _master argument.

Usage

The setUpgradeMaster function has the following usage syntax and arguments:

  Argument Type Details
1 _master address | Address of the new Upgrade Master
setUpgradeAgent Usage Example
setUpgradeMaster(0x123456789abcdefghijklmnopqrstuvwxyz98765);

canUpgrade

Function Name: canUpgrade
Description: Function to get whether the token can be upgraded or not
Function Type: Constant
Function Visibility: Public
Function Modifiers: N/A
Return Type: bool
Return Details: Returns true as a default; customised in child contracts to fit required conditions

Code

The code for the canUpgrade function is as follows:

canUpgrade Code
function canUpgrade() public constant returns(bool) {
    return true;
}

The canUpgrade function performs the following:

  • returns true. This functionality is overridden in child contracts to provide conditionality for this result.

Usage

The canUpgrade function has the following usage syntax:

getUpgradeState Usage Example
canUpgrade();