Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement token interactions #16

Merged
merged 23 commits into from
Dec 7, 2020
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion contracts/BosonToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ contract BosonToken is ERC20WithPermit, AccessControl {
ERC20WithPermit(name, symbol)
public
{
_mint(msg.sender, 100 * 10 ** uint(decimals));
owner = msg.sender;

_setupRole(MINTER_ROLE, msg.sender);
Expand Down
383 changes: 307 additions & 76 deletions contracts/Cashier.sol

Large diffs are not rendered by default.

5 changes: 1 addition & 4 deletions contracts/ERC20WithPermit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@ contract ERC20WithPermit is IERC20WithPermit {
mapping(address => uint256) public override balanceOf;
mapping(address => mapping(address => uint256)) public override allowance;

// TODO
bytes32 public override DOMAIN_SEPARATOR;
// keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
bytes32
public override constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
bytes32 public override constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry probably we had some misunderstanding on the previous PR. I think it would be helpful if we have the comment here, how this permit hash is constructed, otherwise it just looks like magic.

mapping(address => uint256) public override nonces;

event Approval(
Expand Down
1 change: 0 additions & 1 deletion contracts/IERC20WithPermit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ interface IERC20WithPermit {
uint256 value
) external returns (bool);

// TODO
function DOMAIN_SEPARATOR() external view returns (bytes32);

function PERMIT_TYPEHASH() external pure returns (bytes32);
Expand Down
119 changes: 99 additions & 20 deletions contracts/VoucherKernel.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ contract VoucherKernel is Ownable, usingHelpers {
//promise for an asset could be reusable, but simplified here for brevitbytes32
struct Promise {
bytes32 promiseId;
string assetTitle; //the asset that is offered
uint256 nonce; //the asset that is offered
thecryptofruit marked this conversation as resolved.
Show resolved Hide resolved
address seller; //the seller who created the promise

//we simplify the value for the demoapp, otherwise voucher details would be packed in one bytes32 field value
Expand All @@ -40,10 +40,19 @@ contract VoucherKernel is Ownable, usingHelpers {

uint idx;
}

struct VoucherPaymentMethod {
uint8 paymentMethod;
address addressTokenPrice;
address addressTokenDeposits;
}

address public cashierAddress; //address of the Cashier contract

mapping(bytes32 => Promise) public promises; //promises to deliver goods or services
mapping(address => uint256) public tokenNonces;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment here why the Nonces are used

mapping (uint256 => VoucherPaymentMethod) public paymentDetails; // tokenSupplyId to VoucherPaymentMethod

bytes32[] public promiseKeys;

mapping(address => uint256) public accountSupply;
Expand Down Expand Up @@ -85,12 +94,20 @@ contract VoucherKernel is Ownable, usingHelpers {

event LogPromiseCreated(
bytes32 indexed _promiseId,
string indexed _assetTitle,
uint256 indexed _nonce,
address indexed _seller,
uint256 _validFrom,
uint256 _validTo,
uint256 _idx
);

event LogVoucherDelivered(
uint256 indexed _tokenIdSupply,
uint256 _tokenIdVoucher,
address _issuer,
address _holder,
bytes32 _promiseId
);

event LogVoucherRedeemed(
uint256 _tokenIdVoucher,
Expand Down Expand Up @@ -169,40 +186,39 @@ contract VoucherKernel is Ownable, usingHelpers {
* @notice Creating a new promise for goods or services.
* Can be reused, e.g. for making different batches of these (but not in prototype).
* @param _seller seller of the promise
* @param _assetTitle Name of the asset
* @param _validFrom Start of valid period
* @param _validTo End of valid period
* @param _price Price (payment amount)
* @param _depositSe Seller's deposit
* @param _depositBu Buyer's deposit
*/
function createAssetPromise(
function createTokenSupplyID(
address _seller,
string calldata _assetTitle,
uint256 _validFrom,
uint256 _validTo,
uint256 _price,
uint256 _depositSe,
uint256 _depositBu
uint256 _depositBu,
uint256 _quantity
)
external
onlyFromCashier
returns (bytes32)
returns (uint256)
{

require(_validFrom <= _validTo, "INVALID_VALIDITY_FROM"); //hex"26" FISSION.code(FISSION.Category.Find, FISSION.Status.Above_Range_Overflow)
require(_validTo >= block.timestamp, "INVALID_VALIDITY_TO"); //hex"24" FISSION.code(FISSION.Category.Find, FISSION.Status.BelowRange_Underflow)

bytes32 key;
key = keccak256(abi.encodePacked(_assetTitle, _validFrom, _validTo));
key = keccak256(abi.encodePacked(tokenNonces[_seller]++, _validFrom, _validTo));

if (promiseKeys.length > 0) {
require(promiseKeys[promises[key].idx] != key, "PROMISE_ALREADY_EXISTS");
}

promises[key] = Promise({
promiseId: key,
assetTitle: _assetTitle,
nonce: tokenNonces[_seller],
seller: _seller,
validFrom: _validFrom,
validTo: _validTo,
Expand All @@ -214,13 +230,30 @@ contract VoucherKernel is Ownable, usingHelpers {

promiseKeys.push(key);

emit LogPromiseCreated(key, _assetTitle, msg.sender, _validFrom, _validTo, //_price, _depositSe, _depositBu, _complainPeriod, _cancelFaultPeriod,
emit LogPromiseCreated(key, tokenNonces[_seller], _seller, _validFrom, _validTo, //_price, _depositSe, _depositBu, _complainPeriod, _cancelFaultPeriod,
promiseKeys.length - 1);

return key;
}



return createOrder(_seller, key, _quantity);
}

function createPaymentMethod(
uint256 _tokenIdSupply,
uint8 _paymentMethod,
address _tokenPrice,
address _tokenDeposits
)
external
onlyFromCashier
{

paymentDetails[_tokenIdSupply] = VoucherPaymentMethod({
paymentMethod: _paymentMethod,
addressTokenPrice: _tokenPrice,
addressTokenDeposits: _tokenDeposits

});
}

/**
* @notice Create an order for offering a certain quantity of an asset
* This creates a listing in a marketplace, technically as an ERC-1155 non-fungible token with supply.
Expand All @@ -229,8 +262,7 @@ contract VoucherKernel is Ownable, usingHelpers {
* @param _quantity Quantity of assets on offer
*/
function createOrder(address _seller, bytes32 _promiseId, uint256 _quantity)
external
onlyFromCashier
private
returns (uint256)
{
require(_promiseId != bytes32(0), "UNSPECIFIED_PROMISE"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange)
Expand All @@ -256,13 +288,15 @@ contract VoucherKernel is Ownable, usingHelpers {
function fillOrder(uint256 _tokenIdSupply, address _issuer, address _holder)
external
onlyFromCashier
returns (uint256)

{
//checks
checkOrderFillable(_tokenIdSupply, _issuer, _holder);

//close order
return extract721(_issuer, _holder, _tokenIdSupply);
uint256 voucherTokenId = extract721(_issuer, _holder, _tokenIdSupply);

emit LogVoucherDelivered(_tokenIdSupply, voucherTokenId, _issuer, _holder, getPromiseIdFromVoucherId(voucherTokenId));
}


Expand Down Expand Up @@ -750,6 +784,20 @@ contract VoucherKernel is Ownable, usingHelpers {
bytes32 promiseKey = ordersPromise[_tokenIdSupply];
return (promises[promiseKey].price, promises[promiseKey].depositSe, promises[promiseKey].depositBu);
}


/**
* @notice Get Buyer costs required to make an order for a supply token
* @param _tokenIdSupply ID of the supply token
* @return returns a tupple (Payment amount, Buyer's deposit)
*/
function getBuyerOrderCosts(uint256 _tokenIdSupply)
public view
returns (uint256, uint256)
{
bytes32 promiseKey = ordersPromise[_tokenIdSupply];
return (promises[promiseKey].price, promises[promiseKey].depositBu);
}


/**
Expand Down Expand Up @@ -789,7 +837,38 @@ contract VoucherKernel is Ownable, usingHelpers {
{
return tokensContract.ownerOf(_tokenIdVoucher);
}



/**
* @notice Get the address of the token where the price for the supply is held
* @param _tokenIdSupply ID of the voucher token
* @return Address of the token
*/
function getVoucherPriceToken(uint256 _tokenIdSupply)
public view
returns (address)
{
return paymentDetails[_tokenIdSupply].addressTokenPrice;
}

/**
* @notice Get the address of the token where the deposits for the supply are held
* @param _tokenIdSupply ID of the voucher token
* @return Address of the token
*/
function getVoucherDepositToken(uint256 _tokenIdSupply)
public view
returns (address)
{
return paymentDetails[_tokenIdSupply].addressTokenDeposits;
}

function getVoucherPaymentMethod(uint256 _tokenIdSupply)
public view
returns (uint8)
{
return paymentDetails[_tokenIdSupply].paymentMethod;
}

/**
*
Expand Down
11 changes: 9 additions & 2 deletions contracts/usingHelpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ contract usingHelpers {
/* Status of the voucher in 8 bits:
[7:COMMITTED] [6:REDEEMED] [5:REFUNDED] [4:EXPIRED] [3:COMPLAINED] [2:CANCELORFAULT] [1:FINAL] [1:/]
*/


// Those are the payment methods we are using throughout the system.
// Depending on how to user choose to interact with it's funds we store the method, so we could distribute its tokens afterwise
uint8 internal constant ETH_ETH = 1;
uint8 internal constant ETH_TKN = 2;
uint8 internal constant TKN_ETH = 3;
uint8 internal constant TKN_TKN = 4;

struct VoucherStatus {
uint8 status;
bool isPaymentReleased;
Expand Down Expand Up @@ -74,4 +81,4 @@ contract usingHelpers {
{
return _status | ONE << _changeIdx;
}
}
}
Loading