Skip to content

Commit

Permalink
contracts: stake and confirmStakingIntent
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminbollen committed Nov 24, 2017
1 parent 449f1de commit d7b8b67
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 26 deletions.
4 changes: 3 additions & 1 deletion contracts/Hasher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ contract Hasher {
_conversionRate);
}

function hashMintingIntent(
function hashStakingIntent(
bytes32 _uuid,
address _account,
uint256 _accountNonce,
address _beneficiary,
uint256 _amountST,
uint256 _amountUT,
uint256 _escrowUnlockHeight)
Expand All @@ -61,6 +62,7 @@ contract Hasher {
_uuid,
_account,
_accountNonce,
_beneficiary,
_amountST,
_amountUT,
_escrowUnlockHeight);
Expand Down
3 changes: 0 additions & 3 deletions contracts/Registrar.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,5 @@ contract Registrar is OpsManaged {
{
}





}
123 changes: 113 additions & 10 deletions contracts/utilityChain/OpenSTUtility.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,41 @@ contract OpenSTUtility is Hasher, OpsManaged {
* Structures
*/
struct RegisteredToken {
address tokenAddress;
UtilityTokenInterface token;
address registrar;
}


struct Mint {
bytes32 uuid;
address staker;
address beneficiary;
uint256 amount;
uint256 unlockHeight;
}

struct Redemption {
bytes32 uuid;
address redeemer;
uint256 amountUT;
uint256 escrowUnlockHeight;
}
/*
* Events
*/
event RequestedBrandedToken(address indexed _requester, address indexed _token,
bytes32 _uuid, string _symbol, string _name, uint256 _conversionRate);
event RegisteredBrandedToken(address indexed _registrar, address indexed _token,
bytes32 _uuid, string _symbol, string _name, uint256 _conversionRate, address _requester);
event StakingIntentConfirmed(bytes32 indexed _uuid, bytes32 indexed _stakingIntentHash,
address _staker, address _beneficiary, uint256 _amountST, uint256 _amountUT, uint256 unlockHeight);
event ProcessedMint(bytes32 indexed _uuid, bytes32 indexed _stakingIntentHash, address _staker,
address _beneficiary, uint256 _amount);

/*
* Constants
*/
string public constant STPRIME_SYMBOL = "STP";
string public constant STPRIME_SYMBOL = "STP";
string public constant STPRIME_NAME = "SimpleTokenPrime";
uint8 public constant TOKEN_DECIMALS = 18;
uint256 public constant DECIMALSFACTOR = 10**uint256(TOKEN_DECIMALS);
Expand All @@ -63,7 +83,6 @@ contract OpenSTUtility is Hasher, OpsManaged {
/*
* Storage
*/
// mapping()
/// store address of Simple Token Prime
address public simpleTokenPrime;
bytes32 public uuidSTPrime;
Expand All @@ -79,7 +98,16 @@ contract OpenSTUtility is Hasher, OpsManaged {
/// symbol reserved for unique API routes
/// and resolves to address
mapping(bytes32 /* hashSymbol */ => address /* UtilityToken */) public symbolRoute;

/// nonce makes the staking process atomic across the two-phased process
/// and protects against replay attack on (un)staking proofs during the process.
/// On the value chain nonces need to strictly increase by one; on the utility
/// chain the nonce need to strictly increase (as one value chain can have multiple
/// utility chains)
mapping(address /* (un)staker */ => uint256) nonces;
/// store the ongoing mints and redemptions
mapping(bytes32 /* stakingIntentHash */ => Mint) mints;
mapping(bytes32 /* redemptionIntentHash*/ => Redemption) redemptions;

/*
* Modifiers
*/
Expand Down Expand Up @@ -119,8 +147,8 @@ contract OpenSTUtility is Hasher, OpsManaged {
uuidSTPrime);

registeredTokens[uuidSTPrime] = RegisteredToken({
tokenAddress: simpleTokenPrime,
registrar: registrar
token: UtilityTokenInterface(simpleTokenPrime),
registrar: registrar
});

// lock name and symbol route for ST'
Expand Down Expand Up @@ -252,11 +280,11 @@ contract OpenSTUtility is Hasher, OpsManaged {
require(uuid == _checkUuid);
require(_brandedToken.uuid() == _checkUuid);

assert(registeredTokens[uuid].tokenAddress == address(0));
assert(address(registeredTokens[uuid].token) == address(0));

registeredTokens[uuid] = RegisteredToken({
tokenAddress: _brandedToken,
registrar: registrar
token: _brandedToken,
registrar: registrar
});

// register name to registrar
Expand All @@ -270,11 +298,86 @@ contract OpenSTUtility is Hasher, OpsManaged {
return uuid;
}

function confirmStakingIntent(
bytes32 _uuid,
address _staker,
uint256 _stakerNonce,
address _beneficiary,
uint256 _amountST,
uint256 _amountUT,
uint256 _stakingUnlockHeight,
bytes32 _stakingIntentHash)
external
onlyRegistrar
returns (uint256 unlockHeight)
{
require(address(registeredTokens[_uuid].token) != address(0));

require(nonces[_staker] < _stakerNonce);
require(_amountST > 0);
require(_amountUT > 0);
// escrowunlockheight needs to be checked against the core that tracks the value chain
require(_stakingUnlockHeight > 0);
require(_stakingIntentHash != "");

unlockHeight = block.number + BLOCKS_TO_WAIT_SHORT;
nonces[_staker] = _stakerNonce;

bytes32 stakingIntentHash = hashStakingIntent(
_uuid,
_staker,
_stakerNonce,
_beneficiary,
_amountST,
_amountUT,
_stakingUnlockHeight
);

require(stakingIntentHash == _stakingIntentHash);

mints[stakingIntentHash] = Mint({
uuid: _uuid,
staker: _staker,
beneficiary: _beneficiary,
amount: _amountUT,
unlockHeight: unlockHeight
});

StakingIntentConfirmed(_uuid, _stakingIntentHash, _staker, _beneficiary, _amountST,
_amountUT, unlockHeight);

return unlockHeight;
}

function processMinting(
bytes32 _stakingIntentHash)
external
returns (address tokenAddress)
{
require(_stakingIntentHash != "");

Mint storage mint = mints[_stakingIntentHash];
require(mint.staker == msg.sender);
require(mint.unlockHeight > block.number);

UtilityTokenInterface token = registeredTokens[mint.uuid].token;
tokenAddress = address(token);
require(tokenAddress != address(0));

require(token.mint(mint.beneficiary, mint.amount));

ProcessedMint(mint.uuid, _stakingIntentHash, mint.staker, mint.beneficiary, mint.amount);

delete mints[_stakingIntentHash];

return tokenAddress;
}


/*
* Operation functions
*/
/// @dev TODO: add events to trigger for each action

function addNameReservation(
bytes32 _hashName,
address _requester)
Expand Down
17 changes: 9 additions & 8 deletions contracts/utilityChain/UtilityTokenAbstract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ pragma solidity ^0.4.17;

import "../SafeMath.sol";
import "../ProtocolVersioned.sol";
import "./UtilityTokenInterface.sol";

/// @title UtilityToken abstract
contract UtilityTokenAbstract is ProtocolVersioned {
contract UtilityTokenAbstract is ProtocolVersioned, UtilityTokenInterface {
using SafeMath for uint256;

/*
Expand Down Expand Up @@ -61,13 +62,13 @@ contract UtilityTokenAbstract is ProtocolVersioned {
totalTokenSupply = 0;
}

/// @dev transfer full claim to beneficiary
function claim(address _beneficiary) public returns (bool success);
/// @dev Mint new utility token into
function mint(address _beneficiary, uint256 _amount) public returns (bool success);
/// @dev Burn utility tokens after having redeemed them
/// through the protocol for the staked Simple Token
function burn(address _burner, uint256 _amount) public payable returns (bool success);
// /// @dev transfer full claim to beneficiary
// function claim(address _beneficiary) public returns (bool success);
// /// @dev Mint new utility token into
// function mint(address _beneficiary, uint256 _amount) public returns (bool success);
// /// @dev Burn utility tokens after having redeemed them
// /// through the protocol for the staked Simple Token
// function burn(address _burner, uint256 _amount) public payable returns (bool success);

/// @dev Get totalTokenSupply as view so that child cannot edit
function totalSupply()
Expand Down
36 changes: 36 additions & 0 deletions contracts/utilityChain/UtilityTokenInterface.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
pragma solidity ^0.4.17;

// Copyright 2017 OpenST Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ----------------------------------------------------------------------------
// contracts/utilityChain/UtilityTokenInterface.sol
//
// http://www.simpletoken.org/
//
// ----------------------------------------------------------------------------

contract UtilityTokenInterface {

/// @dev transfer full claim to beneficiary
function claim(address _beneficiary) public returns (bool success);
/// @dev Mint new utility token into claim for beneficiary
function mint(address _beneficiary, uint256 _amount) public returns (bool success);
/// @dev Burn utility tokens after having redeemed them
/// through the protocol for the staked Simple Token
function burn(address _burner, uint256 _amount) public payable returns (bool success);

/// @dev Get totalTokenSupply as view so that child cannot edit
function totalSupply() public view returns (uint256 supply);
}
Loading

0 comments on commit d7b8b67

Please sign in to comment.