mirror of
https://github.com/status-im/contracts.git
synced 2025-02-23 12:08:47 +00:00
presigned token
This commit is contained in:
parent
14832d927f
commit
d12683b9b4
3
.gitignore
vendored
3
.gitignore
vendored
@ -30,3 +30,6 @@ coverage.json
|
||||
# node
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
|
||||
# ide
|
||||
.vs/
|
26
contracts/status/SNTPreSigned.sol
Normal file
26
contracts/status/SNTPreSigned.sol
Normal file
@ -0,0 +1,26 @@
|
||||
pragma solidity ^0.4.11;
|
||||
|
||||
import "../token/MiniMeTokenPreSigned.sol";
|
||||
import "../token/MiniMeTokenPreSignedFactory.sol";
|
||||
|
||||
/*
|
||||
Copyright 2017, Jarrad Hope (Status Research & Development GmbH)
|
||||
*/
|
||||
|
||||
contract SNTPreSigned is MiniMeTokenPreSigned {
|
||||
// @dev SNT constructor just parametrizes the MiniMeIrrevocableVestedToken constructor
|
||||
function SNTPreSigned(address _oldToken)
|
||||
MiniMeToken(
|
||||
new MiniMeTokenPreSignedFactory(),
|
||||
_oldToken, // parent token
|
||||
block.number, // snapshot block
|
||||
"Status Network Token", // Token name
|
||||
18, // Decimals
|
||||
"SNT", // Symbol
|
||||
true // Enable transfers
|
||||
)
|
||||
public
|
||||
{
|
||||
|
||||
}
|
||||
}
|
160
contracts/token/MiniMeTokenPreSigned.sol
Normal file
160
contracts/token/MiniMeTokenPreSigned.sol
Normal file
@ -0,0 +1,160 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
import "./MiniMeToken.sol";
|
||||
|
||||
/**
|
||||
* @title StatusConstitution
|
||||
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
|
||||
* @dev MiniMeToken that supports pre-signed methods transfer(address,uint256) and approveAndCall(address,uint256,bytes)
|
||||
*/
|
||||
contract MiniMeTokenPreSigned is MiniMeToken {
|
||||
|
||||
mapping (address => uint256) public nonce;
|
||||
|
||||
/**
|
||||
* @notice Include a presigned `transfer(address,uint256)`
|
||||
* @param _sigV Signature V
|
||||
* @param _sigR Signature R
|
||||
* @param _sigS Signature S
|
||||
* @param _to The address of the recipient
|
||||
* @param _value The amount of tokens to be transferred
|
||||
* @param _gasPrice How much tokens willing to pay per gas
|
||||
* @param _nonce Presigned transaction number.
|
||||
*/
|
||||
function transferPreSigned(
|
||||
uint8 _sigV,
|
||||
bytes32 _sigR,
|
||||
bytes32 _sigS,
|
||||
address _to,
|
||||
uint256 _value,
|
||||
uint256 _gasPrice,
|
||||
uint256 _nonce
|
||||
)
|
||||
public
|
||||
{
|
||||
uint256 _gas = msg.gas;
|
||||
//"a9059cbb": "transfer(address,uint256)",
|
||||
bytes32 txHash = keccak256(byte(0x19), byte(0), address(this), bytes4(0xa9059cbb), _to, _value, _gasPrice, _nonce);
|
||||
address recovered = ecrecover(txHash, _sigV, _sigR, _sigS);
|
||||
require(recovered > 0x0);
|
||||
require(nonce[recovered] == _nonce);
|
||||
nonce[recovered]++;
|
||||
require(doTransfer(recovered, _to, _value));
|
||||
_gas = 21000 + (_gas - msg.gas);
|
||||
if (_gasPrice > 0) {
|
||||
require(doTransfer(recovered, msg.sender, _gasPrice * _gas));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Include a presigned `approveAndCall(address,uint256,bytes)`
|
||||
* @param _sigV Signature V
|
||||
* @param _sigR Signature R
|
||||
* @param _sigS Signature S
|
||||
* @param _spender The address of the recipient
|
||||
* @param _amount The amount of tokens to be transferred
|
||||
* @param _extraData option data to send to contract
|
||||
* @param _gasPrice How much tokens willing to pay per gas
|
||||
* @param _nonce Presigned transaction number.
|
||||
*/
|
||||
function approveAndCallPreSigned(
|
||||
uint8 _sigV,
|
||||
bytes32 _sigR,
|
||||
bytes32 _sigS,
|
||||
address _spender,
|
||||
uint256 _amount,
|
||||
bytes _extraData,
|
||||
uint256 _gasPrice,
|
||||
uint256 _nonce
|
||||
)
|
||||
public
|
||||
{
|
||||
uint256 _gas = msg.gas;
|
||||
require(transfersEnabled);
|
||||
//"cae9ca51": "approveAndCall(address,uint256,bytes)"
|
||||
bytes32 txHash = keccak256(byte(0x19), byte(0), address(this), bytes4(0xcae9ca51), _spender, _amount, _extraData, _gasPrice, _nonce);
|
||||
address recovered = ecrecover(txHash, _sigV, _sigR, _sigS);
|
||||
require(recovered > 0x0);
|
||||
require(nonce[recovered] == _nonce);
|
||||
nonce[recovered]++;
|
||||
|
||||
require((_amount == 0) || (allowed[recovered][_spender] == 0));
|
||||
if (isContract(controller)) {
|
||||
require(TokenController(controller).onApprove(recovered, _spender, _amount));
|
||||
}
|
||||
allowed[recovered][_spender] = _amount;
|
||||
Approval(recovered, _spender, _amount);
|
||||
ApproveAndCallFallBack(_spender).receiveApproval(
|
||||
recovered,
|
||||
_amount,
|
||||
this,
|
||||
_extraData
|
||||
);
|
||||
_gas = 21000 + (_gas - msg.gas);
|
||||
if (_gasPrice > 0) {
|
||||
require(doTransfer(recovered, msg.sender, _gasPrice*_gas));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Include batches of presigned `approveAndCall(address,uint256,bytes)`
|
||||
* @param _sigV Signature V
|
||||
* @param _sigR Signature R
|
||||
* @param _sigS Signature S
|
||||
* @param _spender The address of the recipient
|
||||
* @param _amount The amount of tokens to be transferred
|
||||
* @param _extraData option data to send to contract
|
||||
* @param _gasPrice How much tokens willing to pay per gas
|
||||
* @param _nonce Presigned transaction number.
|
||||
*/
|
||||
function approveAndCallPreSigned(
|
||||
uint8[] _sigV,
|
||||
bytes32[] _sigR,
|
||||
bytes32[] _sigS,
|
||||
address[] _spender,
|
||||
uint256[] _amount,
|
||||
bytes[] _extraData,
|
||||
uint256[] _gasPrice,
|
||||
uint256[] _nonce
|
||||
)
|
||||
public
|
||||
{
|
||||
uint len = _sigR.length;
|
||||
require(len == _sigS.length && len == _sigV.length);
|
||||
for (uint i = 0; i < len; i++) {
|
||||
approveAndCallPreSigned(_sigV[i], _sigR[i], _sigS[i], _spender[i], _amount[i], _extraData[i], _gasPrice[i], _nonce[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @notice Include batches of presigned `transfer(address,uint256)`
|
||||
* @param _sigV Signature V
|
||||
* @param _sigR Signature R
|
||||
* @param _sigS Signature S
|
||||
* @param _to The address of the recipient
|
||||
* @param _value The amount of tokens to be transferred
|
||||
* @param _gasPrice How much tokens willing to pay per gas
|
||||
* @param _nonce Presigned transaction number.
|
||||
*/
|
||||
function transferPreSigned(
|
||||
uint8[] _sigV,
|
||||
bytes32[] _sigR,
|
||||
bytes32[] _sigS,
|
||||
address[] _to,
|
||||
uint256[] _value,
|
||||
uint256[] _gasPrice,
|
||||
uint256[] _nonce
|
||||
)
|
||||
public
|
||||
{
|
||||
uint len = _sigR.length;
|
||||
require(len == _sigS.length && len == _sigV.length);
|
||||
for (uint i = 0; i < len; i++) {
|
||||
transferPreSigned(_sigV[i], _sigR[i], _sigS[i], _to[i], _value[i], _gasPrice[i], _nonce[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
45
contracts/token/MiniMeTokenPreSignedFactory.sol
Normal file
45
contracts/token/MiniMeTokenPreSignedFactory.sol
Normal file
@ -0,0 +1,45 @@
|
||||
pragma solidity ^0.4.11;
|
||||
|
||||
import "./MiniMeTokenPreSigned.sol";
|
||||
|
||||
////////////////
|
||||
// MiniMeTokenFactory
|
||||
////////////////
|
||||
|
||||
/// @dev This contract is used to generate clone contracts from a contract.
|
||||
/// In solidity this is the way to create a contract from a contract of the
|
||||
/// same class
|
||||
contract MiniMeTokenPreSignedFactory {
|
||||
|
||||
/// @notice Update the DApp by creating a new token with new functionalities
|
||||
/// the msg.sender becomes the controller of this clone token
|
||||
/// @param _parentToken Address of the token being cloned
|
||||
/// @param _snapshotBlock Block of the parent token that will
|
||||
/// determine the initial distribution of the clone token
|
||||
/// @param _tokenName Name of the new token
|
||||
/// @param _decimalUnits Number of decimals of the new token
|
||||
/// @param _tokenSymbol Token Symbol for the new token
|
||||
/// @param _transfersEnabled If true, tokens will be able to be transferred
|
||||
/// @return The address of the new token contract
|
||||
function createCloneToken(
|
||||
address _parentToken,
|
||||
uint _snapshotBlock,
|
||||
string _tokenName,
|
||||
uint8 _decimalUnits,
|
||||
string _tokenSymbol,
|
||||
bool _transfersEnabled
|
||||
) returns (MiniMeTokenPreSigned) {
|
||||
MiniMeTokenPreSigned newToken = new MiniMeTokenPreSigned(
|
||||
this,
|
||||
_parentToken,
|
||||
_snapshotBlock,
|
||||
_tokenName,
|
||||
_decimalUnits,
|
||||
_tokenSymbol,
|
||||
_transfersEnabled
|
||||
);
|
||||
|
||||
newToken.changeController(msg.sender);
|
||||
return newToken;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user