Skip to content

Commit

Permalink
working on a dropper proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
Amxx committed May 17, 2019
1 parent ae15c6e commit 19950b7
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 49 deletions.
2 changes: 1 addition & 1 deletion contracts/Migrations.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity ^0.5.7;
pragma solidity ^0.5.8;

import "openzeppelin-solidity/contracts/ownership/Ownable.sol";

Expand Down
5 changes: 2 additions & 3 deletions contracts/PriceOracle.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity ^0.5.7;
pragma solidity ^0.5.8;
pragma experimental ABIEncoderV2;

import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
Expand Down Expand Up @@ -28,8 +28,7 @@ contract PriceOracle is Ownable, IexecDoracle
// Use _iexecHubAddr to force use of custom iexechub, leave 0x0 for autodetect
constructor(address _iexecHubAddr)
public IexecDoracle(_iexecHubAddr)
{
}
{}

function updateEnv(
address _authorizedApp
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
pragma solidity ^0.5.7;
pragma solidity ^0.5.8;
pragma experimental ABIEncoderV2;

import "./libs/Buffer.sol";
import "./PriceOracle.sol";
import "../libs/Buffer.sol";
import "../PriceOracle.sol";

contract PriceOracleSubmitter is PriceOracle
contract PriceOracleRequester is PriceOracle
{
using Buffer for Buffer.buffer;

// Use _iexecHubAddr to force use of custom iexechub, leave 0x0 for autodetect
constructor(address _iexecHubAddr)
public PriceOracle(_iexecHubAddr)
{
}
{}

function uint2str(uint256 _i)
public pure returns (string memory)
Expand Down Expand Up @@ -68,8 +66,8 @@ contract PriceOracleSubmitter is PriceOracle
order.params = makeParams("BTC", "USD", 9, now); // string
order.salt = bytes32(0); // bytes32 → OK ?

m_iexecClerk.signRequestOrder(order);
m_iexecClerk.broadcastRequestOrder(order);
iexecClerk.signRequestOrder(order);
iexecClerk.broadcastRequestOrder(order);
}

}
119 changes: 119 additions & 0 deletions contracts/requesterproxy/IexecRequesterProxy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
pragma solidity ^0.5.8;
pragma experimental ABIEncoderV2;

import "iexec-doracle-base/contracts/IexecInterface.sol";
import "iexec-solidity/contracts/ERC20_Token/ERC20.sol";

contract IexecRequesterProxy is IexecInterface, ERC20
{
IERC20 public baseToken;

using IexecODBLibOrders for bytes32;
using IexecODBLibOrders for IexecODBLibOrders.RequestOrder;

struct OrderDetail
{
uint256 maxprice;
address requester;
}
mapping(bytes32 => OrderDetail) m_orderDetails;
mapping(bytes32 => bool) m_dealUnlocked;

// Use _iexecHubAddr to force use of custom iexechub, leave 0x0 for autodetect
constructor(address _iexecHubAddr)
public IexecInterface(_iexecHubAddr)
{
baseToken = iexecClerk.token();
}

function deposit(uint256 _amount)
external returns (bool)
{
require(baseToken.transferFrom(msg.sender, address(this), _amount));
require(baseToken.approve(address(iexecClerk), _amount));
require(iexecClerk.deposit(_amount));

_mint(msg.sender, _amount);
return true;
}

function depositFor(uint256 _amount, address _target)
public returns (bool)
{
require(_target != address(0));

require(baseToken.transferFrom(msg.sender, address(this), _amount));
require(baseToken.approve(address(iexecClerk), _amount));
require(iexecClerk.deposit(_amount));

_mint(_target, _amount);
return true;
}

function submit(IexecODBLibOrders.RequestOrder memory order)
public
{
// compute order price and total necessary lock.
uint256 maxprice = order.appmaxprice
.add(order.datasetmaxprice)
.add(order.workerpoolmaxprice);
uint256 lock = maxprice.mul(order.volume);

// lock price from requester
_transfer(msg.sender, address(this), lock);

// record details for refund of unspent tokens
bytes32 requestorderHash = order.hash().toEthTypedStructHash(iexecClerk.EIP712DOMAIN_SEPARATOR());

OrderDetail storage od = m_orderDetails[requestorderHash];
require(od.requester == address(0));
od.maxprice = maxprice;
od.requester = msg.sender;

// set requester
order.requester = address(this);

// sign and broadcast
iexecClerk.signRequestOrder(order);
iexecClerk.broadcastRequestOrder(order);
}

function cancel(IexecODBLibOrders.RequestOrder memory order)
public
{
bytes32 requestorderHash = order.hash().toEthTypedStructHash(iexecClerk.EIP712DOMAIN_SEPARATOR());
OrderDetail storage od = m_orderDetails[requestorderHash];

require(msg.sender == od.requester);

uint256 consumed = iexecClerk.viewConsumed(requestorderHash);
uint256 refund = od.maxprice.mul(order.volume.sub(consumed));

_transfer(address(this), od.requester, refund);
iexecClerk.cancelRequestOrder(order);
}

function unlockUnspent(bytes32 requestorderhash, uint256 firstTask)
public
{
bytes32 dealid = keccak256(abi.encodePacked(requestorderhash, firstTask));

// only refund the difference once per deal
require(!m_dealUnlocked[dealid]);
m_dealUnlocked[dealid] = true;

IexecODBLibCore.Deal memory deal = iexecClerk.viewDeal(dealid);
OrderDetail storage od = m_orderDetails[requestorderhash];

uint256 actualprice = deal.app.price
.add(deal.dataset.price)
.add(deal.workerpool.price);

uint256 delta = actualprice
.sub(od.maxprice);

_transfer(address(this), od.requester, delta.mul(deal.botSize));
_burn (address(this), actualprice.mul(deal.botSize));
}

}
30 changes: 21 additions & 9 deletions migrations/2_deploy_contracts.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
var RLC = artifacts.require("rlc-faucet-contract/RLC");
var IexecODBLibOrders = artifacts.require("iexec-poco/IexecODBLibOrders");
var IexecHub = artifacts.require("iexec-poco/IexecHub");
var IexecClerk = artifacts.require("iexec-poco/IexecClerk");
var AppRegistry = artifacts.require("iexec-poco/AppRegistry");
var DatasetRegistry = artifacts.require("iexec-poco/DatasetRegistry");
var WorkerpoolRegistry = artifacts.require("iexec-poco/WorkerpoolRegistry");
// var PriceOracle = artifacts.require("PriceOracle");
var PriceOracle = artifacts.require("PriceOracleSubmitter");
var RLC = artifacts.require("rlc-faucet-contract/RLC");
var IexecODBLibOrders = artifacts.require("iexec-poco/IexecODBLibOrders");
var IexecHub = artifacts.require("iexec-poco/IexecHub");
var IexecClerk = artifacts.require("iexec-poco/IexecClerk");
var AppRegistry = artifacts.require("iexec-poco/AppRegistry");
var DatasetRegistry = artifacts.require("iexec-poco/DatasetRegistry");
var WorkerpoolRegistry = artifacts.require("iexec-poco/WorkerpoolRegistry");

var PriceOracle = artifacts.require("PriceOracle");
var PriceOracleRequester = artifacts.require("PriceOracleRequester");
var IexecRequesterProxy = artifacts.require("IexecRequesterProxy");

module.exports = async function(deployer, network, accounts)
{
Expand Down Expand Up @@ -91,4 +93,14 @@ module.exports = async function(deployer, network, accounts)
PriceOracleInstance = await PriceOracle.deployed();
console.log("PriceOracle deployed at address: " + PriceOracleInstance.address);

await deployer.deploy(PriceOracleRequester, IexecHubInstance.address);
PriceOracleRequesterInstance = await PriceOracleRequester.deployed();
console.log("PriceOracleRequester deployed at address: " + PriceOracleRequesterInstance.address);

await deployer.link(IexecODBLibOrders, IexecRequesterProxy);
// await deployer.deploy(IexecRequesterProxy);
// await deployer.deploy(IexecRequesterProxy, IexecHubInstance.address);
// IexecRequesterProxyInstance = await IexecRequesterProxy.deployed();
// console.log("IexecRequesterProxy deployed at address: " + IexecRequesterProxyInstance.address);

};
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
"dependencies": {
"chai": "^4.2.0",
"ethereumjs-util": "^5.2.0",
"iexec-doracle-base": "^0.0.2",
"iexec-doracle-base": "^0.0.4",
"iexec-poco": "^3.0.35",
"iexec-solidity": "^0.0.6",
"iexec-solidity": "^0.0.7",
"multiaddr": "^6.0.6",
"openzeppelin-solidity": "^2.2.0",
"openzeppelin-test-helpers": "^0.1.5",
Expand Down
4 changes: 1 addition & 3 deletions test/PriceOracle.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ var WorkerpoolRegistry = artifacts.require("../node_modules/iexec-poco/contracts
var App = artifacts.require("../node_modules/iexec-poco/contracts/App.sol");
var Dataset = artifacts.require("../node_modules/iexec-poco/contracts/Dataset.sol");
var Workerpool = artifacts.require("../node_modules/iexec-poco/contracts/Workerpool.sol");

// var PriceOracle = artifacts.require("./PriceOracle.sol");
var PriceOracle = artifacts.require("./PriceOracleSubmitter.sol");
var PriceOracle = artifacts.require("./PriceOracle.sol");

const { shouldFail } = require('openzeppelin-test-helpers');
const multiaddr = require('multiaddr');
Expand Down
42 changes: 20 additions & 22 deletions test/PriceOracleSubmitter.js → test/PriceOracleRequester.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
var RLC = artifacts.require("../node_modules/rlc-faucet-contract/contracts/RLC.sol");
var IexecHub = artifacts.require("../node_modules/iexec-poco/contracts/IexecHub.sol");
var IexecClerk = artifacts.require("../node_modules/iexec-poco/contracts/IexecClerk.sol");
var AppRegistry = artifacts.require("../node_modules/iexec-poco/contracts/AppRegistry.sol");
var DatasetRegistry = artifacts.require("../node_modules/iexec-poco/contracts/DatasetRegistry.sol");
var WorkerpoolRegistry = artifacts.require("../node_modules/iexec-poco/contracts/WorkerpoolRegistry.sol");
var App = artifacts.require("../node_modules/iexec-poco/contracts/App.sol");
var Dataset = artifacts.require("../node_modules/iexec-poco/contracts/Dataset.sol");
var Workerpool = artifacts.require("../node_modules/iexec-poco/contracts/Workerpool.sol");

// var PriceOracle = artifacts.require("./PriceOracle.sol");
var PriceOracle = artifacts.require("./PriceOracleSubmitter.sol");
var RLC = artifacts.require("../node_modules/rlc-faucet-contract/contracts/RLC.sol");
var IexecHub = artifacts.require("../node_modules/iexec-poco/contracts/IexecHub.sol");
var IexecClerk = artifacts.require("../node_modules/iexec-poco/contracts/IexecClerk.sol");
var AppRegistry = artifacts.require("../node_modules/iexec-poco/contracts/AppRegistry.sol");
var DatasetRegistry = artifacts.require("../node_modules/iexec-poco/contracts/DatasetRegistry.sol");
var WorkerpoolRegistry = artifacts.require("../node_modules/iexec-poco/contracts/WorkerpoolRegistry.sol");
var App = artifacts.require("../node_modules/iexec-poco/contracts/App.sol");
var Dataset = artifacts.require("../node_modules/iexec-poco/contracts/Dataset.sol");
var Workerpool = artifacts.require("../node_modules/iexec-poco/contracts/Workerpool.sol");
var PriceOracleRequester = artifacts.require("./PriceOracleRequester.sol");

const { shouldFail } = require('openzeppelin-test-helpers');
const multiaddr = require('multiaddr');
Expand All @@ -22,7 +20,7 @@ function extractEvents(txMined, address, name)
return txMined.logs.filter((ev) => { return ev.address == address && ev.event == name });
}

contract('PriceOracle', async (accounts) => {
contract('PriceOracleRequester', async (accounts) => {

assert.isAtLeast(accounts.length, 10, "should have at least 10 accounts");
let iexecAdmin = accounts[0];
Expand Down Expand Up @@ -58,7 +56,7 @@ contract('PriceOracle', async (accounts) => {

var date, value, id, details, result;

var PriceOracleInstance = null;
var PriceOracleRequesterInstance = null;

var totalgas = 0;

Expand All @@ -77,9 +75,9 @@ contract('PriceOracle', async (accounts) => {
AppRegistryInstance = await AppRegistry.deployed();
DatasetRegistryInstance = await DatasetRegistry.deployed();
WorkerpoolRegistryInstance = await WorkerpoolRegistry.deployed();
PriceOracleInstance = await PriceOracle.deployed();
PriceOracleRequesterInstance = await PriceOracleRequester.deployed();

console.log("PriceOracleInstance:", PriceOracleInstance.address);
console.log("PriceOracleRequesterInstance:", PriceOracleRequesterInstance.address);

odbtools.setup({
name: "iExecODB",
Expand Down Expand Up @@ -203,7 +201,7 @@ contract('PriceOracle', async (accounts) => {
});

it("[Setup] Oracle setup", async () => {
await PriceOracleInstance.updateEnv(
await PriceOracleRequesterInstance.updateEnv(
AppInstance.address,
constants.NULL.ADDRESS,
WorkerpoolInstance.address,
Expand Down Expand Up @@ -245,7 +243,7 @@ contract('PriceOracle', async (accounts) => {
wallets.addressToPrivate(scheduler)
);

const tx = await PriceOracleInstance.submit({ from: user, gas: constants.AMOUNT_GAS_PROVIDED });
const tx = await PriceOracleRequesterInstance.submit({ from: user, gas: constants.AMOUNT_GAS_PROVIDED });
const [ evABI ] = IexecClerkInstance.abi.filter(o => o.name === 'BroadcastRequestOrder' && o.type == 'event');
const [ ev ] = tx.receipt.rawLogs.filter(l => l.topics.includes(evABI.signature));
const decoded = web3.eth.abi.decodeLog(evABI.inputs, ev.data, ev.topics);
Expand Down Expand Up @@ -341,21 +339,21 @@ contract('PriceOracle', async (accounts) => {
});

it("Process Oracle", async () => {
const valueBefore = await PriceOracleInstance.values(id);
const valueBefore = await PriceOracleRequesterInstance.values(id);
assert.equal(valueBefore.date, 0 );
assert.equal(valueBefore.details, "");
assert.equal(valueBefore.value, 0 );

txMined = await PriceOracleInstance.processResult(task);
events = extractEvents(txMined, PriceOracleInstance.address, "ValueUpdated");
txMined = await PriceOracleRequesterInstance.processResult(task);
events = extractEvents(txMined, PriceOracleRequesterInstance.address, "ValueUpdated");
assert.equal(events[0].args.id, id );
assert.equal(events[0].args.oldDate.toNumber(), 0 );
assert.equal(events[0].args.oldValue.toNumber(), 0 );
assert.equal(events[0].args.newDate.toNumber(), date );
assert.equal(events[0].args.newValue.toNumber(), value);

totalgas += txMined.receipt.gasUsed;
const valueAfter = await PriceOracleInstance.values(id);
const valueAfter = await PriceOracleRequesterInstance.values(id);
assert.equal(valueAfter.date, date );
assert.equal(valueAfter.details, details);
assert.equal(valueAfter.value, value );
Expand Down

0 comments on commit 19950b7

Please sign in to comment.