DCIPs/assets/eip-3525/contracts/ERC3525Example.sol

155 lines
5.5 KiB
Solidity

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ERC3525.sol";
import "StringConvertor.sol";
import "base64.sol";
/**
* This is a demo contract for how to generate slot
*/
contract ERC3525Example is ERC3525 {
using StringConvertor for uint256;
/**
* @notice Properties of the slot, which determine the value of slot.
*/
struct SlotDetail {
string name;
string description;
string image;
address underlying;
uint8 vestingType;
uint32 maturity;
uint32 term;
}
// slot => slotDetail
mapping(uint256 => SlotDetail) private _slotDetails;
uint256 constant _externalMintMaxId = 1000000000;
constructor( string memory name_, string memory symbol_, uint8 decimals_) ERC3525(name_, symbol_, decimals_) {}
function mint( string memory slotName_, string memory slotDescription_, string memory slotImage_,
uint256 tokenId_, address underlying_, uint8 vestingType_, uint32 maturity_, uint32 term_, uint256 value_) public {
require(tokenId_ < _externalMintMaxId, "ERC3525: tokenId is too large");
uint256 slot = _getSlot(underlying_, vestingType_, maturity_, term_);
_slotDetails[slot] = SlotDetail({
name: slotName_,
description: slotDescription_,
image: slotImage_,
underlying: underlying_,
vestingType: vestingType_,
maturity: maturity_,
term: term_
});
ERC3525._mintValue(_msgSender(), tokenId_, slot, value_);
}
function getSlotDetail(uint256 slot_) public view returns (SlotDetail memory) {
return _slotDetails[slot_];
}
function _getNewTokenId(uint256 fromTokenId_) internal virtual override returns (uint256) {
return 1000000000 + fromTokenId_;
}
/**
* @dev Generate the value of slot by utilizing keccak256 algorithm to calculate the hash
* value of multi properties.
*/
function _getSlot( address underlying_, uint8 vestingType_, uint32 maturity_, uint32 term_) internal pure virtual returns (uint256 slot_) {
return
uint256(
keccak256(
abi.encodePacked(
underlying_,
vestingType_,
maturity_,
term_
)
)
);
}
function slotURI(uint256 slot_) public view virtual override returns (string memory) {
return
string(
abi.encodePacked(
/* solhint-disable */
"data:application/json;base64,",
Base64.encode(
abi.encodePacked(
'{"name":"',
_slotDetails[slot_].name,
'","description":"',
_slotDetails[slot_].description,
'","image":"',
_slotDetails[slot_].image,
'","properties":',
_slotProperties(slot_),
"}"
)
)
/* solhint-enable */
)
);
}
/**
* @dev Generate the content of the `properties` field of `slotURI`.
*/
function _slotProperties(uint256 slot_) internal view returns (string memory) {
SlotDetail storage slotDetail = _slotDetails[slot_];
return
string(
/* solhint-disable */
abi.encodePacked(
"[",
abi.encodePacked(
'{"name":"underlying",',
'"description":"Address of the underlying token locked in this contract.",',
'"value":"',
Strings.toHexString(
uint256(uint160(slotDetail.underlying))
),
'",',
'"order":1,',
'"display_type":"string"},'
),
abi.encodePacked(
'{"name":"vesting_type",',
'"description":"Vesting type that represents the releasing mode of underlying assets.",',
'"value":',
uint256(slotDetail.vestingType).toString(),
",",
'"order":2,',
'"display_type":"number"},'
),
abi.encodePacked(
'{"name":"maturity",',
'"description":"Maturity that all underlying assets would be completely released.",',
'"value":',
uint256(slotDetail.maturity).toString(),
",",
'"order":3,',
'"display_type":"date"},'
),
abi.encodePacked(
'{"name":"term",',
'"description":"The length of the locking period (in seconds)",',
'"value":',
uint256(slotDetail.term).toString(),
",",
'"order":4,',
'"display_type":"number"}'
),
"]"
)
/* solhint-enable */
);
}
}