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
|
||||||
node_modules/
|
node_modules/
|
||||||
npm-debug.log
|
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