From 4a8a4739701f5644f5aceb8c6ef1d1e447a25ad6 Mon Sep 17 00:00:00 2001 From: satyam Date: Wed, 10 Oct 2018 23:13:17 +0530 Subject: [PATCH] intial setup --- contracts/Migrations.sol | 23 +++ .../PartialFungibleToken.sol | 157 +----------------- contracts/interfaces/ERC777Token.sol | 38 +++++ contracts/interfaces/IERC1410.sol | 148 +++++++++++++++++ eip-1400.md => eip/eip-1400.md | 0 eip-1410.md => eip/eip-1410.md | 0 migrations/1_initial_migration.js | 5 + package.json | 32 ++++ truffle.js | 18 ++ 9 files changed, 273 insertions(+), 148 deletions(-) create mode 100644 contracts/Migrations.sol rename ReferenceImplementation.sol => contracts/PartialFungibleToken.sol (56%) create mode 100644 contracts/interfaces/ERC777Token.sol create mode 100644 contracts/interfaces/IERC1410.sol rename eip-1400.md => eip/eip-1400.md (100%) rename eip-1410.md => eip/eip-1410.md (100%) create mode 100644 migrations/1_initial_migration.js create mode 100644 package.json create mode 100644 truffle.js diff --git a/contracts/Migrations.sol b/contracts/Migrations.sol new file mode 100644 index 0000000..c4efb65 --- /dev/null +++ b/contracts/Migrations.sol @@ -0,0 +1,23 @@ +pragma solidity ^0.4.23; + +contract Migrations { + address public owner; + uint public last_completed_migration; + + constructor() public { + owner = msg.sender; + } + + modifier restricted() { + if (msg.sender == owner) _; + } + + function setCompleted(uint completed) public restricted { + last_completed_migration = completed; + } + + function upgrade(address new_address) public restricted { + Migrations upgraded = Migrations(new_address); + upgraded.setCompleted(last_completed_migration); + } +} diff --git a/ReferenceImplementation.sol b/contracts/PartialFungibleToken.sol similarity index 56% rename from ReferenceImplementation.sol rename to contracts/PartialFungibleToken.sol index 601abda..1921dbe 100644 --- a/ReferenceImplementation.sol +++ b/contracts/PartialFungibleToken.sol @@ -1,150 +1,11 @@ -// This is a work in progress currently based on an older version of the specification. - pragma solidity ^0.4.24; -interface IERCPFT { - - /// @notice A descriptive name for tokens in this contract - function name() external view returns (string _name); - - /// @notice An abbreviated name for tokens in this contract - function symbol() external view returns (string _symbol); - - /// @notice Counts the sum of all tranche balances assigned to an owner - /// @param _owner An address for whom to query the balance - /// @return The number of tokens owned by `_owner`, possibly zero - function balanceOf(address _owner) external view returns (uint256); - - /// @notice Counts the balance associated with a specific tranche assigned to an owner - /// @param _tranche The tranche for which to query the balance - /// @param _owner An address for whom to query the balance - /// @return The number of tokens owned by `_owner` with the metadata associated with `_tranche`, possibly zero - function balanceOfTranche(bytes32 _tranche, address _owner) external view returns (uint256); - - /// @notice Count all tokens tracked by this contract - /// @return A count of all tokens tracked by this contract - function totalSupply() external view returns (uint256); - - /// @notice Transfers the ownership of tokens from a specified tranche from one address to another address - /// @param _tranche The tranche from which to transfer tokens - /// @param _to The address to which to transfer tokens to - /// @param _amount The amount of tokens to transfer from `_tranche` - /// @param _data Additional data attached to the transfer of tokens - /// @return A reason code related to the success of the send operation - /// @return The tranche to which the transferred tokens were allocated for the _to address - function sendTranche(bytes32 _tranche, address _to, uint256 _amount, bytes _data) external returns (byte, bytes32); - - /// @notice Transfers the ownership of tokens from a specified tranche from one address to another address - /// @param _tranche The tranche from which to transfer tokens - /// @param _from The address from which to transfer tokens from - /// @param _to The address to which to transfer tokens to - /// @param _amount The amount of tokens to transfer from `_tranche` - /// @param _data Additional data attached to the transfer of tokens - /// @param _operatorData Additional data attached to the transfer of tokens by the operator - /// @return A reason code related to the success of the send operation - /// @return The tranche to which the transferred tokens were allocated for the _to address - function operatorSendTranche(bytes32 _tranche, address _from, address _to, uint256 _amount, bytes _data, bytes _operatorData) external returns (byte, bytes32); - - /// @notice Allows enumeration over an individual owners tranches - /// @param _owner An address over which to enumerate tranches - /// @param _index The index of the tranche - /// @return The tranche key corresponding to `_index` - function trancheByIndex(address _owner, uint256 _index) external view returns (bytes32); - - /// @notice Enables caller to determine the count of tranches owned by an address - /// @param _owner An address over which to enumerate tranches - /// @return The number of tranches owned by an `_owner` - function tranchesOf(address _owner) external view returns (uint256); - - /// @notice Defines a list of operators which can operate over all addresses and tranches - /// @return The list of default operators - function defaultOperators() public view returns (address[]); - - /// @notice Defines a list of operators which can operate over all addresses for the specified tranche - /// @return The list of default operators for `_tranche` - function defaultOperatorsTranche(bytes32 _tranche) public view returns (address[]); - - /// @notice Authorises an operator for all tranches of `msg.sender` - /// @param _operator An address which is being authorised - function authorizeOperator(address _operator) public; - - /// @notice Authorises an operator for a given tranche of `msg.sender` - /// @param _tranche The tranche to which the operator is authorised - /// @param _operator An address which is being authorised - function authorizeOperatorTranche(bytes32 _tranche, address _operator) public; - - /// @notice Revokes authorisation of an operator previously given for all tranches of `msg.sender` - /// @param _operator An address which is being de-authorised - function revokeOperator(address _operator) public; - - /// @notice Revokes authorisation of an operator previously given for a specified tranche of `msg.sender` - /// @param _tranche The tranche to which the operator is de-authorised - /// @param _operator An address which is being de-authorised - function revokeOperatorTranche(bytes32 _tranche, address _operator) public; - - /// @notice Determines whether `_operator` is an operator for all tranches of `_owner` - /// @param _operator The operator to check - /// @param _owner The owner to check - /// @return Whether the `_operator` is an operator for all tranches of `_owner` - function isOperatorFor(address _operator, address _owner) public view returns (bool); - - /// @notice Determines whether `_operator` is an operator for a specified tranche of `_owner` - /// @param _tranche The tranche to check - /// @param _operator The operator to check - /// @param _owner The owner to check - /// @return Whether the `_operator` is an operator for a specified tranche of `_owner` - function isOperatorForTranche(bytes32 _tranche, address _operator, address _owner) public view returns (bool); - - /// @notice Increases totalSupply and the corresponding amount of the specified owners tranche - /// @param _tranche The tranche to allocate the increase in balance - /// @param _owner The owner whose balance should be increased - /// @param _amount The amount by which to increase the balance - /// @param _data Additional data attached to the minting of tokens - /// @return A reason code related to the success of the mint operation - function mint(bytes32 _tranche, address _owner, uint256 _amount, bytes _data) public returns (byte reason); - - /// @notice Decreases totalSupply and the corresponding amount of the specified owners tranche - /// @param _tranche The tranche to allocate the decrease in balance - /// @param _owner The owner whose balance should be decreased - /// @param _amount The amount by which to decrease the balance - /// @param _data Additional data attached to the burning of tokens - /// @return A reason code related to the success of the burn operation - function burn(bytes32 _tranche, address _owner, uint256 _amount, bytes _data) public returns (byte reason); - - /// @notice This emits on any successful call to `mint` - event Minted(address indexed owner, bytes32 tranche, uint256 amount, bytes data); - - /// @notice This emits on any successful call to `burn` - event Burnt(address indexed owner, bytes32 tranche, uint256 amount, bytes data); - - /// @notice This emits on any successful transfer or minting of tokens - event SentTranche( - address indexed operator, - address indexed from, - address indexed to, - bytes32 fromTranche, - bytes32 toTranche, - uint256 amount, - bytes data, - bytes operatorData - ); - - /// @notice This emits on any successful operator approval for all tranches, excluding default operators - event AuthorizedOperator(address indexed operator, address indexed owner); - - /// @notice This emits on any successful operator approval for a single tranche, excluding default tranche operators - event AuthorizedOperatorTranche(bytes32 indexed tranche, address indexed operator, address indexed owner); - - /// @notice This emits on any successful revoke of an operators approval for all tranches - event RevokedOperator(address indexed operator, address indexed owner); - - /// @notice This emits on any successful revoke of an operators approval for a single tranche - event RevokedOperatorTranche(bytes32 indexed tranche, address indexed operator, address indexed owner); - -} +import "./interfaces/IERC1410.sol"; -// Reference implementation of partially-fungible tokens -contract PFT is IERCPFT { +/** + * @title Reference implementation of partially-fungible tokens + */ +contract PartialFungibleToken is IERC1410 { // Represents a fungible set of tokens. struct Tranche { @@ -174,7 +35,7 @@ contract PFT is IERCPFT { mapping (address => mapping (address => bool)) approvals; // Returns sum of amounts over all owned fungible token sets for investor - function balanceOf(address _owner) public view returns (uint256) { + function balanceOf(address _owner) external view returns (uint256) { return balances[_owner]; } @@ -185,7 +46,7 @@ contract PFT is IERCPFT { // Transfers tokens from the sender to the _to address, keeping the _tranche the same function sendTranche(bytes32 _tranche, address _to, uint256 _amount, bytes _data) external returns (byte, bytes32) { - (byte reason, bytes32 newTranche) = _sendTranche(msg.sender, _to, _tranche, _amount, _data, ''); + (byte reason, bytes32 newTranche) = _sendTranche(msg.sender, _to, _amount, _tranche, _data, ''); emit SentTranche( address(0), msg.sender, @@ -199,9 +60,9 @@ contract PFT is IERCPFT { return (reason, newTranche); } - function _sendTranche(bytes32 _tranche, address _from, address _to, uint256 _amount, bytes _data, bytes _operatorData) internal returns (byte, bytes32) { + function _sendTranche(address _from, address _to, uint256 _amount, bytes32 _tranche, bytes _data, bytes _operatorData) internal returns (byte, bytes32) { - if (balanceOfTranche(msg.sender, _tranche) < _amount) { + if (balanceOfTranche(_from, _tranche) < _amount) { return (hex"00", bytes32('')); } diff --git a/contracts/interfaces/ERC777Token.sol b/contracts/interfaces/ERC777Token.sol new file mode 100644 index 0000000..a1171e5 --- /dev/null +++ b/contracts/interfaces/ERC777Token.sol @@ -0,0 +1,38 @@ +pragma solidity ^0.4.24; + +/** + * @title Interface of ERC777 standard + * @dev ref. https://eips.ethereum.org/EIPS/eip-777 + */ + +interface ERC777Token { + function name() external view returns (string); + function symbol() external view returns (string); + function totalSupply() external view returns (uint256); + function balanceOf(address owner) external view returns (uint256); + function granularity() external view returns (uint256); + + function defaultOperators() external view returns (address[]); + function authorizeOperator(address operator) public; + function revokeOperator(address operator) public; + function isOperatorFor(address operator, address tokenHolder) public view returns (bool); + + function send(address to, uint256 amount, bytes data) external; + function operatorSend(address from, address to, uint256 amount, bytes data, bytes operatorData) external; + + function burn(uint256 amount, bytes data) public; + function operatorBurn(address from, uint256 amount, bytes data, bytes operatorData) external; + + event Sent( + address indexed operator, + address indexed from, + address indexed to, + uint256 amount, + bytes data, + bytes operatorData + ); + event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData); + event Burned(address indexed operator, address indexed from, uint256 amount, bytes operatorData); + event AuthorizedOperator(address indexed operator, address indexed tokenHolder); + event RevokedOperator(address indexed operator, address indexed tokenHolder); +} \ No newline at end of file diff --git a/contracts/interfaces/IERC1410.sol b/contracts/interfaces/IERC1410.sol new file mode 100644 index 0000000..7d24989 --- /dev/null +++ b/contracts/interfaces/IERC1410.sol @@ -0,0 +1,148 @@ +pragma solidity ^0.4.24; + +/** + * @title Interface of ERC1410 standard + * @dev ref. https://github.com/ethereum/EIPs/issues/1410 + * @dev ERC1410 is dependent on the ERC777 + */ + + interface IERC1410 { + + /// @notice A descriptive name for tokens in this contract + function name() external view returns (string _name); + + /// @notice An abbreviated name for tokens in this contract + function symbol() external view returns (string _symbol); + + /// @notice Counts the sum of all tranche balances assigned to an owner + /// @param _owner An address for whom to query the balance + /// @return The number of tokens owned by `_owner`, possibly zero + function balanceOf(address _owner) external view returns (uint256); + + /// @notice Counts the balance associated with a specific tranche assigned to an owner + /// @param _tranche The tranche for which to query the balance + /// @param _owner An address for whom to query the balance + /// @return The number of tokens owned by `_owner` with the metadata associated with `_tranche`, possibly zero + function balanceOfTranche(bytes32 _tranche, address _owner) external view returns (uint256); + + /// @notice Count all tokens tracked by this contract + /// @return A count of all tokens tracked by this contract + function totalSupply() external view returns (uint256); + + /// @notice Transfers the ownership of tokens from a specified tranche from one address to another address + /// @param _tranche The tranche from which to transfer tokens + /// @param _to The address to which to transfer tokens to + /// @param _amount The amount of tokens to transfer from `_tranche` + /// @param _data Additional data attached to the transfer of tokens + /// @return A reason code related to the success of the send operation + /// @return The tranche to which the transferred tokens were allocated for the _to address + function sendTranche(bytes32 _tranche, address _to, uint256 _amount, bytes _data) external returns (byte, bytes32); + + /// @notice Transfers the ownership of tokens from a specified tranche from one address to another address + /// @param _tranche The tranche from which to transfer tokens + /// @param _from The address from which to transfer tokens from + /// @param _to The address to which to transfer tokens to + /// @param _amount The amount of tokens to transfer from `_tranche` + /// @param _data Additional data attached to the transfer of tokens + /// @param _operatorData Additional data attached to the transfer of tokens by the operator + /// @return A reason code related to the success of the send operation + /// @return The tranche to which the transferred tokens were allocated for the _to address + function operatorSendTranche(bytes32 _tranche, address _from, address _to, uint256 _amount, bytes _data, bytes _operatorData) external returns (byte, bytes32); + + /// @notice Allows enumeration over an individual owners tranches + /// @param _owner An address over which to enumerate tranches + /// @param _index The index of the tranche + /// @return The tranche key corresponding to `_index` + function trancheByIndex(address _owner, uint256 _index) external view returns (bytes32); + + /// @notice Enables caller to determine the count of tranches owned by an address + /// @param _owner An address over which to enumerate tranches + /// @return The number of tranches owned by an `_owner` + function tranchesOf(address _owner) external view returns (uint256); + + /// @notice Defines a list of operators which can operate over all addresses and tranches + /// @return The list of default operators + function defaultOperators() public view returns (address[]); + + /// @notice Defines a list of operators which can operate over all addresses for the specified tranche + /// @return The list of default operators for `_tranche` + function defaultOperatorsTranche(bytes32 _tranche) public view returns (address[]); + + /// @notice Authorises an operator for all tranches of `msg.sender` + /// @param _operator An address which is being authorised + function authorizeOperator(address _operator) public; + + /// @notice Authorises an operator for a given tranche of `msg.sender` + /// @param _tranche The tranche to which the operator is authorised + /// @param _operator An address which is being authorised + function authorizeOperatorTranche(bytes32 _tranche, address _operator) public; + + /// @notice Revokes authorisation of an operator previously given for all tranches of `msg.sender` + /// @param _operator An address which is being de-authorised + function revokeOperator(address _operator) public; + + /// @notice Revokes authorisation of an operator previously given for a specified tranche of `msg.sender` + /// @param _tranche The tranche to which the operator is de-authorised + /// @param _operator An address which is being de-authorised + function revokeOperatorTranche(bytes32 _tranche, address _operator) public; + + /// @notice Determines whether `_operator` is an operator for all tranches of `_owner` + /// @param _operator The operator to check + /// @param _owner The owner to check + /// @return Whether the `_operator` is an operator for all tranches of `_owner` + function isOperatorFor(address _operator, address _owner) public view returns (bool); + + /// @notice Determines whether `_operator` is an operator for a specified tranche of `_owner` + /// @param _tranche The tranche to check + /// @param _operator The operator to check + /// @param _owner The owner to check + /// @return Whether the `_operator` is an operator for a specified tranche of `_owner` + function isOperatorForTranche(bytes32 _tranche, address _operator, address _owner) public view returns (bool); + + /// @notice Increases totalSupply and the corresponding amount of the specified owners tranche + /// @param _tranche The tranche to allocate the increase in balance + /// @param _owner The owner whose balance should be increased + /// @param _amount The amount by which to increase the balance + /// @param _data Additional data attached to the minting of tokens + /// @return A reason code related to the success of the mint operation + function mint(bytes32 _tranche, address _owner, uint256 _amount, bytes _data) public returns (byte reason); + + /// @notice Decreases totalSupply and the corresponding amount of the specified owners tranche + /// @param _tranche The tranche to allocate the decrease in balance + /// @param _owner The owner whose balance should be decreased + /// @param _amount The amount by which to decrease the balance + /// @param _data Additional data attached to the burning of tokens + /// @return A reason code related to the success of the burn operation + function burn(bytes32 _tranche, address _owner, uint256 _amount, bytes _data) public returns (byte reason); + + /// @notice This emits on any successful call to `mint` + event Minted(address indexed owner, bytes32 tranche, uint256 amount, bytes data); + + /// @notice This emits on any successful call to `burn` + event Burnt(address indexed owner, bytes32 tranche, uint256 amount, bytes data); + + /// @notice This emits on any successful transfer or minting of tokens + event SentTranche( + address indexed operator, + address indexed from, + address indexed to, + bytes32 fromTranche, + bytes32 toTranche, + uint256 amount, + bytes data, + bytes operatorData + ); + + /// @notice This emits on any successful operator approval for all tranches, excluding default operators + event AuthorizedOperator(address indexed operator, address indexed owner); + + /// @notice This emits on any successful operator approval for a single tranche, excluding default tranche operators + event AuthorizedOperatorTranche(bytes32 indexed tranche, address indexed operator, address indexed owner); + + /// @notice This emits on any successful revoke of an operators approval for all tranches + event RevokedOperator(address indexed operator, address indexed owner); + + /// @notice This emits on any successful revoke of an operators approval for a single tranche + event RevokedOperatorTranche(bytes32 indexed tranche, address indexed operator, address indexed owner); + +} \ No newline at end of file diff --git a/eip-1400.md b/eip/eip-1400.md similarity index 100% rename from eip-1400.md rename to eip/eip-1400.md diff --git a/eip-1410.md b/eip/eip-1410.md similarity index 100% rename from eip-1410.md rename to eip/eip-1410.md diff --git a/migrations/1_initial_migration.js b/migrations/1_initial_migration.js new file mode 100644 index 0000000..4d5f3f9 --- /dev/null +++ b/migrations/1_initial_migration.js @@ -0,0 +1,5 @@ +var Migrations = artifacts.require("./Migrations.sol"); + +module.exports = function(deployer) { + deployer.deploy(Migrations); +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..a3344b6 --- /dev/null +++ b/package.json @@ -0,0 +1,32 @@ +{ + "name": "eip-spec", + "version": "0.1.0", + "description": "Security Token Standard", + "main": "truffle.js", + "directories": { + "test": "test" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/SecurityTokenStandard/EIP-Spec.git" + }, + "keywords": [ + "SecurityTokens", + "EIP", + "Securites", + "ERC1400", + "ERC1410", + "PFT", + "ERC777", + "ERC1066" + ], + "author": "Polymath Inc", + "license": "MIT", + "bugs": { + "url": "https://github.com/SecurityTokenStandard/EIP-Spec/issues" + }, + "homepage": "https://github.com/SecurityTokenStandard/EIP-Spec#readme" +} diff --git a/truffle.js b/truffle.js new file mode 100644 index 0000000..0855df1 --- /dev/null +++ b/truffle.js @@ -0,0 +1,18 @@ +/* + * NB: since truffle-hdwallet-provider 0.0.5 you must wrap HDWallet providers in a + * function when declaring them. Failure to do so will cause commands to hang. ex: + * ``` + * mainnet: { + * provider: function() { + * return new HDWalletProvider(mnemonic, 'https://mainnet.infura.io/') + * }, + * network_id: '1', + * gas: 4500000, + * gasPrice: 10000000000, + * }, + */ + +module.exports = { + // See + // to customize your Truffle configuration! +};