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

Add match orders boost feature on voucher #16

Merged
merged 28 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4d0e438
add matchOrdersBoost access
gfournieriExec Apr 26, 2024
498f466
erase typo
gfournieriExec Apr 28, 2024
9caa1f5
update changelog
gfournieriExec Apr 29, 2024
91ecfa8
factorize match orders / boost functions with modifiers
gfournieriExec Apr 29, 2024
bba6389
Merge branch 'develop' into feature/match-orders-boost
gfournieriExec Apr 29, 2024
7932b61
add iExecpoco address to _debitVoucherAndTransfer input
gfournieriExec Apr 29, 2024
c759284
add Todo taskPrice
gfournieriExec Apr 29, 2024
4bcdf32
erase `before` when initial is present in constant name
gfournieriExec Apr 29, 2024
12fcf0e
erase .wait and mine
gfournieriExec Apr 29, 2024
6ba5992
Set voucherWithAnyoneSigner more global
gfournieriExec Apr 29, 2024
042040e
add voucher with signers at top of file
gfournieriExec Apr 29, 2024
57f5d61
remove useless voucher.connect
gfournieriExec Apr 29, 2024
3ba7e21
update with list of voucher with signer
gfournieriExec Apr 30, 2024
fb00830
update todo
gfournieriExec Apr 30, 2024
99968d0
Update private _debitVoucherAndTransfer function name
gfournieriExec Apr 30, 2024
e932f3f
Update test/beacon/Voucher.test.ts
gfournieriExec Apr 30, 2024
13d1489
moved no voucher revert tests at the end
gfournieriExec Apr 30, 2024
c57eee2
update params of _debitVoucherAndTransferNonSponsoredAmount
gfournieriExec Apr 30, 2024
c8ea51e
add sponsored value and check emission of events
gfournieriExec Apr 30, 2024
ed4f440
update `to be equal` in voucher test script
gfournieriExec Apr 30, 2024
99d9d4a
update test name typo
gfournieriExec Apr 30, 2024
bb6bda7
add partial sponsoring test
gfournieriExec Apr 30, 2024
74a554d
no need to check equal zero
gfournieriExec Apr 30, 2024
e466a27
Update test/beacon/Voucher.test.ts
gfournieriExec Apr 30, 2024
fe5fc1c
update typo
gfournieriExec Apr 30, 2024
c67cd27
add OrdersBoostMatchedWithVoucher event arg and moved to up
gfournieriExec Apr 30, 2024
fb8ef6d
check that requester decrease balance after match orders boost
gfournieriExec Apr 30, 2024
1812470
Merge branch 'develop' into feature/match-orders-boost
gfournieriExec Apr 30, 2024
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: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## vNEXT
- Match orders boost through voucher. (#16)
- Use hardhat deploy. (#15)
- Upload coverage reports to Codecov. (#14)
- Clean some TODOs. (#13)
Expand Down
7 changes: 7 additions & 0 deletions contracts/beacon/IVoucher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface IVoucher {
event AccountAuthorized(address indexed account);
event AccountUnauthorized(address indexed account);
event OrdersMatchedWithVoucher(bytes32 dealId);
event OrdersBoostMatchedWithVoucher(bytes32 dealId);

function authorizeAccount(address account) external;
function unauthorizeAccount(address account) external;
Expand All @@ -18,6 +19,12 @@ interface IVoucher {
IexecLibOrders_v5.WorkerpoolOrder calldata workerpoolOrder,
IexecLibOrders_v5.RequestOrder calldata requestOrder
) external returns (bytes32);
function matchOrdersBoost(
IexecLibOrders_v5.AppOrder calldata appOrder,
IexecLibOrders_v5.DatasetOrder calldata datasetOrder,
IexecLibOrders_v5.WorkerpoolOrder calldata workerpoolOrder,
IexecLibOrders_v5.RequestOrder calldata requestOrder
) external returns (bytes32);

function getVoucherHub() external view returns (address);
function getType() external view returns (uint256);
Expand Down
130 changes: 109 additions & 21 deletions contracts/beacon/Voucher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pragma solidity ^0.8.20;

import {IexecLibOrders_v5} from "@iexec/poco/contracts/libs/IexecLibOrders_v5.sol";
import {IexecPoco1} from "@iexec/poco/contracts/modules/interfaces/IexecPoco1.v8.sol";
import {IexecPocoBoost} from "@iexec/poco/contracts/modules/interfaces/IexecPocoBoost.sol";
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IVoucherHub} from "../IVoucherHub.sol";
Expand All @@ -29,6 +30,21 @@ contract Voucher is OwnableUpgradeable, IVoucher {
mapping(bytes32 dealId => uint256) _sponsoredAmounts;
}

modifier onlyAuthorized() {
VoucherStorage storage $ = _getVoucherStorage();
require(
msg.sender == owner() || $._authorizedAccounts[msg.sender],
"Voucher: sender is not authorized"
);
_;
}

modifier onlyNotExpired() {
VoucherStorage storage $ = _getVoucherStorage();
require(block.timestamp < $._expiration, "Voucher: voucher is expired");
_;
}

/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
Expand Down Expand Up @@ -91,31 +107,18 @@ contract Voucher is OwnableUpgradeable, IVoucher {
) external returns (bytes32 dealId) {
// TODO add onlyAuthorized
// TODO check expiration
uint256 appPrice = appOrder.appprice;
uint256 datasetPrice = datasetOrder.datasetprice;
uint256 workerpoolPrice = workerpoolOrder.workerpoolprice;
VoucherStorage storage $ = _getVoucherStorage();
IVoucherHub voucherHub = IVoucherHub($._voucherHub);
uint256 sponsoredAmount = voucherHub.debitVoucher(
address iexecPoco = voucherHub.getIexecPoco();
uint256 sponsoredAmount = _debitVoucherAndTransferNonSponsoredAmount(
$._type,
appOrder.app,
appPrice,
datasetOrder.dataset,
datasetPrice,
workerpoolOrder.workerpool,
workerpoolPrice
$._voucherHub,
zguesmi marked this conversation as resolved.
Show resolved Hide resolved
iexecPoco,
appOrder,
datasetOrder,
workerpoolOrder,
requestOrder
);
uint256 dealPrice = appPrice + datasetPrice + workerpoolPrice;
zguesmi marked this conversation as resolved.
Show resolved Hide resolved
address iexecPoco = voucherHub.getIexecPoco();
if (sponsoredAmount != dealPrice) {
// Transfer non-sponsored amount from the iExec account of the
// requester to the iExec account of the voucher
IERC20(iexecPoco).transferFrom(
requestOrder.requester,
address(this),
dealPrice - sponsoredAmount
);
}
dealId = IexecPoco1(iexecPoco).sponsorMatchOrders(
appOrder,
datasetOrder,
Expand All @@ -127,6 +130,45 @@ contract Voucher is OwnableUpgradeable, IVoucher {
return dealId;
}

/**
* Match orders boost on Poco. Eligible assets prices will be debited from the
* voucher if possible, then non-sponsored amount will be debited from the
* iExec account of the requester.
*
* @param appOrder The app order.
* @param datasetOrder The dataset order.
* @param workerpoolOrder The workerpool order.
* @param requestOrder The request order.
*/
function matchOrdersBoost(
IexecLibOrders_v5.AppOrder calldata appOrder,
IexecLibOrders_v5.DatasetOrder calldata datasetOrder,
IexecLibOrders_v5.WorkerpoolOrder calldata workerpoolOrder,
IexecLibOrders_v5.RequestOrder calldata requestOrder
) external onlyAuthorized onlyNotExpired returns (bytes32 dealId) {
VoucherStorage storage $ = _getVoucherStorage();
IVoucherHub voucherHub = IVoucherHub($._voucherHub);
address iexecPoco = voucherHub.getIexecPoco();
uint256 sponsoredAmount = _debitVoucherAndTransferNonSponsoredAmount(
$._type,
$._voucherHub,
iexecPoco,
appOrder,
datasetOrder,
workerpoolOrder,
requestOrder
);
dealId = IexecPocoBoost(iexecPoco).sponsorMatchOrdersBoost(
appOrder,
datasetOrder,
workerpoolOrder,
requestOrder
);
$._sponsoredAmounts[dealId] = sponsoredAmount;
emit OrdersBoostMatchedWithVoucher(dealId);
return dealId;
}

/**
* Retrieve the address of the voucher hub associated with the voucher.
* @return voucherHubAddress The address of the voucher hub.
Expand Down Expand Up @@ -196,4 +238,50 @@ contract Voucher is OwnableUpgradeable, IVoucher {
$.slot := VOUCHER_STORAGE_LOCATION
}
}

/**
* @dev Debit voucher and transfer non-sponsored amount from requester's account.
*
* @param appOrder The app order.
* @param datasetOrder The dataset order.
* @param workerpoolOrder The workerpool order.
* @param requestOrder The request order.
zguesmi marked this conversation as resolved.
Show resolved Hide resolved
*
* @return sponsoredAmount The amount sponsored by the voucher.
*/
function _debitVoucherAndTransferNonSponsoredAmount(
uint256 voucherTypeId,
address voucherHub,
address iexecPoco,
IexecLibOrders_v5.AppOrder calldata appOrder,
IexecLibOrders_v5.DatasetOrder calldata datasetOrder,
IexecLibOrders_v5.WorkerpoolOrder calldata workerpoolOrder,
IexecLibOrders_v5.RequestOrder calldata requestOrder
) private returns (uint256 sponsoredAmount) {
uint256 appPrice = appOrder.appprice;
uint256 datasetPrice = datasetOrder.datasetprice;
uint256 workerpoolPrice = workerpoolOrder.workerpoolprice;

sponsoredAmount = IVoucherHub(voucherHub).debitVoucher(
voucherTypeId,
appOrder.app,
appPrice,
datasetOrder.dataset,
datasetPrice,
workerpoolOrder.workerpool,
workerpoolPrice
);
// TODO: Compute volume and set dealPrice = taskPrice * volume instead of curent dealPrice
uint256 dealPrice = appPrice + datasetPrice + workerpoolPrice;

if (sponsoredAmount != dealPrice) {
// Transfer non-sponsored amount from the iExec account of the
// requester to the iExec account of the voucher
IERC20(iexecPoco).transferFrom(
requestOrder.requester,
address(this),
dealPrice - sponsoredAmount
);
}
}
}
20 changes: 20 additions & 0 deletions contracts/mocks/IexecPocoMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
*/
contract IexecPocoMock is ERC20 {
bool public shouldRevertOnSponsorMatchOrders = false;
bool public shouldRevertOnSponsorMatchOrdersBoost = false;

constructor() ERC20("Staked RLC", "SRLC") {
_mint(msg.sender, 1000000);
Expand All @@ -32,7 +33,26 @@ contract IexecPocoMock is ERC20 {
return keccak256("deal");
}

function sponsorMatchOrdersBoost(
IexecLibOrders_v5.AppOrder calldata appOrder,
IexecLibOrders_v5.DatasetOrder calldata datasetOrder,
IexecLibOrders_v5.WorkerpoolOrder calldata workerpoolOrder,
IexecLibOrders_v5.RequestOrder calldata
) external returns (bytes32 dealId) {
if (shouldRevertOnSponsorMatchOrdersBoost) {
revert("IexecPocoMock: Failed to sponsorMatchOrdersBoost");
}
_burn(
msg.sender,
appOrder.appprice + datasetOrder.datasetprice + workerpoolOrder.workerpoolprice
);
return keccak256("deal");
}

function willRevertOnSponsorMatchOrders() external {
shouldRevertOnSponsorMatchOrders = true;
}
function willRevertOnSponsorMatchOrdersBoost() external {
shouldRevertOnSponsorMatchOrdersBoost = true;
}
}
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading