Skip to content

Instantly share code, notes, and snippets.

@ernestognw
Created July 5, 2019 18:16
Show Gist options
  • Save ernestognw/8bf79316d824bbd31ecfff7088bd10a5 to your computer and use it in GitHub Desktop.
Save ernestognw/8bf79316d824bbd31ecfff7088bd10a5 to your computer and use it in GitHub Desktop.
ERC1400Standard.sol
pragma solidity ^0.4.24;
import "https://gist.githubusercontent.com/MauPIslas/8f6fa6d7babfc3b5ed9fe494899178b6/raw/1f877d680277ba656ac8fcb9110b9fb135a21072/ERC1400Operator.sol";
import "https://raw.githubusercontent.com/SecurityTokenStandard/EIP-Spec/master/contracts/ERC1410/IERC1410.sol";
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/escrow-exploration/contracts/ownership/Ownable.sol";
contract ERC1410Standard is IERC1410, ERC1410Operator, Ownable {
/// @notice Increases totalSupply and the corresponding amount of the specified owners partition
/// @param _partition The partition to allocate the increase in balance
/// @param _tokenHolder The token holder whose balance should be increased
/// @param _value The amount by which to increase the balance
/// @param _data Additional data attached to the minting of tokens
function issueByPartition(bytes32 _partition, address _tokenHolder, uint256 _value, bytes _data) external onlyOwner {
// Add the function to validate the `_data` parameter
_validateParams(_partition, _value);
require(_tokenHolder != address(0), "Invalid token receiver");
uint256 index = partitionToIndex[_tokenHolder][_partition];
if (index == 0) {
partitions[_tokenHolder].push(Partition(_value, _partition));
partitionToIndex[_tokenHolder][_partition] = partitions[_tokenHolder].length;
} else {
partitions[_tokenHolder][index - 1].amount = partitions[_tokenHolder][index - 1].amount.add(_value);
}
_totalSupply = _totalSupply.add(_value);
balances[_tokenHolder] = balances[_tokenHolder].add(_value);
emit IssuedByPartition(_partition, _tokenHolder, _value, _data);
}
/// @notice Decreases totalSupply and the corresponding amount of the specified partition of msg.sender
/// @param _partition The partition to allocate the decrease in balance
/// @param _value The amount by which to decrease the balance
/// @param _data Additional data attached to the burning of tokens
function redeemByPartition(bytes32 _partition, uint256 _value, bytes _data) external {
// Add the function to validate the `_data` parameter
_redeemByPartition(_partition, msg.sender, address(0), _value, _data, "");
}
/// @notice Decreases totalSupply and the corresponding amount of the specified partition of tokenHolder
/// @dev This function can only be called by the authorised operator.
/// @param _partition The partition to allocate the decrease in balance.
/// @param _tokenHolder The token holder whose balance should be decreased
/// @param _value The amount by which to decrease the balance
/// @param _data Additional data attached to the burning of tokens
/// @param _operatorData Additional data attached to the transfer of tokens by the operator
function operatorRedeemByPartition(bytes32 _partition, address _tokenHolder, uint256 _value, bytes _data, bytes _operatorData) external {
// Add the function to validate the `_data` parameter
// TODO: Add a functionality of verifying the `_operatorData`
require(_tokenHolder != address(0), "Invalid from address");
require(
isOperator(msg.sender, _tokenHolder) || isOperatorForPartition(_partition, msg.sender, _tokenHolder),
"Not authorised"
);
_redeemByPartition(_partition, _tokenHolder, msg.sender, _value, _data, _operatorData);
}
function _redeemByPartition(bytes32 _partition, address _from, address _operator, uint256 _value, bytes _data, bytes _operatorData) internal {
// Add the function to validate the `_data` parameter
_validateParams(_partition, _value);
require(_validPartition(_partition, _from), "Invalid partition");
uint256 index = partitionToIndex[_from][_partition] - 1;
require(partitions[_from][index].amount >= _value, "Insufficient value");
if (partitions[_from][index].amount == _value) {
_deletePartitionForHolder(_from, _partition, index);
} else {
partitions[_from][index].amount = partitions[_from][index].amount.sub(_value);
}
balances[_from] = balances[_from].sub(_value);
_totalSupply = _totalSupply.sub(_value);
emit RedeemedByPartition(_partition, _operator, _from, _value, _data, _operatorData);
}
function _deletePartitionForHolder(address _holder, bytes32 _partition, uint256 index) internal {
if (index != partitions[_holder].length -1) {
partitions[_holder][index] = partitions[_holder][partitions[_holder].length -1];
partitionToIndex[_holder][partitions[_holder][index].partition] = index + 1;
}
delete partitionToIndex[_holder][_partition];
partitions[_holder].length--;
}
function _validateParams(bytes32 _partition, uint256 _value) internal pure {
require(_value != uint256(0), "Zero value not allowed");
require(_partition != bytes32(0), "Invalid partition");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment