aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorGreg Hysen <greg.hysen@gmail.com>2018-12-01 08:43:04 +0800
committerGreg Hysen <greg.hysen@gmail.com>2018-12-19 05:36:05 +0800
commit9f68ac7bbecea109692d62d5555bac67e86c123a (patch)
tree8d0ad6eaaf08b6dbbd057173f531d2af63410565 /packages
parent4e341582ae74d7ab1c52c4e888d72c0c1c78e890 (diff)
downloaddexon-sol-tools-9f68ac7bbecea109692d62d5555bac67e86c123a.tar.gz
dexon-sol-tools-9f68ac7bbecea109692d62d5555bac67e86c123a.tar.zst
dexon-sol-tools-9f68ac7bbecea109692d62d5555bac67e86c123a.zip
Making progress on generalized forwarder
Diffstat (limited to 'packages')
-rw-r--r--packages/contracts/contracts/extensions/CompliantForwarder/CompliantForwarder.sol140
-rw-r--r--packages/contracts/test/extensions/compliant_forwarder.ts35
2 files changed, 98 insertions, 77 deletions
diff --git a/packages/contracts/contracts/extensions/CompliantForwarder/CompliantForwarder.sol b/packages/contracts/contracts/extensions/CompliantForwarder/CompliantForwarder.sol
index b8ba43b15..739f55024 100644
--- a/packages/contracts/contracts/extensions/CompliantForwarder/CompliantForwarder.sol
+++ b/packages/contracts/contracts/extensions/CompliantForwarder/CompliantForwarder.sol
@@ -22,16 +22,20 @@ pragma experimental ABIEncoderV2;
import "../../protocol/Exchange/interfaces/IExchange.sol";
import "../../tokens/ERC721Token/IERC721Token.sol";
import "../../utils/LibBytes/LibBytes.sol";
+import "../../utils/ExchangeSelectors/ExchangeSelectors.sol";
-contract CompliantForwarder {
+contract CompliantForwarder is ExchangeSelectors{
using LibBytes for bytes;
- bytes4 constant internal EXCHANGE_FILL_ORDER_SELECTOR = bytes4(keccak256("fillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),uint256,bytes)"));
IExchange internal EXCHANGE;
IERC721Token internal COMPLIANCE_TOKEN;
- bytes4 constant internal EXCHANGE_FILL_ORDER_SELECTOR_2 = 0xb4be83d5;
+ event ValidatedAddresses (
+ bytes32 selector,
+ address one,
+ address[] addresses
+ );
constructor(address exchange, address complianceToken)
public
@@ -49,84 +53,94 @@ contract CompliantForwarder {
external
{
// Validate `signedFillOrderTransaction`
- bytes4 selector = signedExchangeTransaction.readBytes4(0);
- address makerAddress = 0x00;
+ address[] memory validatedAddresses;
+ bytes32 selectorS;
+ address one;
assembly {
- function getMakerAddress(orderPtr) -> makerAddress {
- let orderOffset := calldataload(orderPtr)
- makerAddress := calldataload(orderOffset)
+ // Adds address to validate
+ function addAddressToValidate(addressToValidate) {
+ // Compute `addressesToValidate` memory location
+ let addressesToValidate_ := mload(0x40)
+ let nAddressesToValidate_ := mload(addressesToValidate_)
+
+ // Increment length
+ nAddressesToValidate_ := add(mload(addressesToValidate_), 1)
+ mstore(addressesToValidate_, nAddressesToValidate_)
+
+ // Append address to validate
+ let offset := mul(32, nAddressesToValidate_)
+ mstore(add(addressesToValidate_, offset), addressToValidate)
}
- switch selector
- case 0xb4be83d500000000000000000000000000000000000000000000000000000000 {
+ function appendMakerAddressFromOrder(paramIndex) -> makerAddress {
let exchangeTxPtr := calldataload(0x44)
-
// Add 0x20 for length offset and 0x04 for selector offset
let orderPtrRelativeToExchangeTx := calldataload(add(0x4, add(exchangeTxPtr, 0x24))) // 0x60
let orderPtr := add(0x4,add(exchangeTxPtr, add(0x24, orderPtrRelativeToExchangeTx)))
-
makerAddress := calldataload(orderPtr)
-
-
- //makerAddress := getMakerAddress(orderPtr)
+ addAddressToValidate(makerAddress)
+ }
+
+
+ // Extract addresses to validate
+ let exchangeTxPtr1 := calldataload(0x44)
+ let selector := and(calldataload(add(0x4, add(0x20, exchangeTxPtr1))), 0xffffffff00000000000000000000000000000000000000000000000000000000)
+ switch selector
+ case 0x097bb70b00000000000000000000000000000000000000000000000000000000 /* batchFillOrders */
+ {
+
+ }
+ case 0x3c28d86100000000000000000000000000000000000000000000000000000000 /* matchOrders */
+ {
+
+ }
+ case 0xb4be83d500000000000000000000000000000000000000000000000000000000 /* fillOrder */
+ {
+ one := appendMakerAddressFromOrder(0)
+ //appendSignerAddress()
}
+ case 0xd46b02c300000000000000000000000000000000000000000000000000000000 /* cancelOrder */ {}
default {
- // revert(0, 100)
+ revert(0, 100)
}
+
+ let addressesToValidate := mload(0x40)
+ let nAddressesToValidate := mload(addressesToValidate)
+ let newMemFreePtr := add(addressesToValidate, add(0x20, mul(mload(addressesToValidate), 0x20)))
+ mstore(0x40, newMemFreePtr)
+
+ // Validate addresses
+ /*
+ let complianceTokenAddress := sload(COMPLIANCE_TOKEN_slot)
+ for {let i := add(32, mload(addressesToValidate))} lt(i, add(addressesToValidate, add(32, mul(nAddressesToValidate, 32)))) {i := add(i, 32)} {
+ // call `COMPLIANCE_TOKEN.balanceOf`
+ let success := call(
+ gas, // forward all gas
+ complianceTokenAddress, // call address of asset proxy
+ 0, // don't send any ETH
+ i, // pointer to start of input
+ 32, // length of input (one padded address)
+ 0, // write output over memory that won't be reused
+ 0 // don't copy output to memory
+ )
+ if eq(success, 0) {
+ revert(0, 100)
+ }
+ }*/
+
+ validatedAddresses := addressesToValidate
+ selectorS := selector
}
-
- /*
- if (selector != 0xb4be83d5) {
- revert("EXCHANGE_TRANSACTION_NOT_FILL_ORDER");
- }*/
-
- // Taker must be compliant
- require(
- COMPLIANCE_TOKEN.balanceOf(signerAddress) > 0,
- "TAKER_UNVERIFIED"
- );
-
- // Extract maker address from fill order transaction and ensure maker is compliant
- // Below is the table of calldata offsets into a fillOrder transaction.
- /**
- ### parameters
- 0x00 ptr<order>
- 0x20 takerAssetFillAmount
- 0x40 ptr<signature>
- ### order
- 0x60 makerAddress
- 0x80 takerAddress
- 0xa0 feeRecipientAddress
- 0xc0 senderAddress
- 0xe0 makerAssetAmount
- 0x100 takerAssetAmount
- 0x120 makerFee
- 0x140 takerFee
- 0x160 expirationTimeSeconds
- 0x180 salt
- 0x1a0 ptr<makerAssetData>
- 0x1c0 ptr<takerAssetData>
- 0x1e0 makerAssetData
- * takerAssetData
- * signature
- ------------------------------
- * Context-dependent offsets; unknown at compile time.
- */
- // Add 0x4 to a given offset to account for the fillOrder selector prepended to `signedFillOrderTransaction`.
- // Add 0xc to the makerAddress since abi-encoded addresses are left padded with 12 bytes.
- // Putting this together: makerAddress = 0x60 + 0x4 + 0xc = 0x70
- //address makerAddress = signedExchangeTransaction.readAddress(0x70);
- require(
- COMPLIANCE_TOKEN.balanceOf(makerAddress) > 0,
- "MAKER_UNVERIFIED"
- );
+
+ emit ValidatedAddresses(selectorS, one, validatedAddresses);
// All entities are verified. Execute fillOrder.
+ /*
EXCHANGE.executeTransaction(
salt,
signerAddress,
signedExchangeTransaction,
signature
- );
+ );*/
}
} \ No newline at end of file
diff --git a/packages/contracts/test/extensions/compliant_forwarder.ts b/packages/contracts/test/extensions/compliant_forwarder.ts
index b916f54c9..4eedffe05 100644
--- a/packages/contracts/test/extensions/compliant_forwarder.ts
+++ b/packages/contracts/test/extensions/compliant_forwarder.ts
@@ -5,6 +5,7 @@ import { BigNumber } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper';
import * as chai from 'chai';
import * as ethUtil from 'ethereumjs-util';
+import * as _ from 'lodash';
import { DummyERC20TokenContract } from '../../generated-wrappers/dummy_erc20_token';
import { ExchangeContract } from '../../generated-wrappers/exchange';
@@ -26,8 +27,10 @@ import { TransactionFactory } from '../utils/transaction_factory';
import { ContractName, ERC20BalancesByOwner, SignedTransaction } from '../utils/types';
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
-import { MethodAbi } from 'ethereum-types';
+import { MethodAbi, AbiDefinition } from 'ethereum-types';
import { AbiEncoder } from '@0x/utils';
+import { Method } from '@0x/utils/lib/src/abi_encoder';
+import { LogDecoder } from '../utils/log_decoder';
chaiSetup.configure();
const expect = chai.expect;
@@ -184,6 +187,18 @@ describe.only(ContractName.CompliantForwarder, () => {
compliantSignedFillOrderTx = takerTransactionFactory.newSignedTransaction(
compliantSignedOrderWithoutExchangeAddressData,
);
+
+ /* generate selectors for every exchange method
+ _.each(exchangeInstance.abi, (abiDefinition: AbiDefinition) => {
+ try {
+ const method = new Method(abiDefinition as MethodAbi);
+ console.log('\n', `// ${method.getDataItem().name}`);
+ console.log(`bytes4 constant ${method.getDataItem().name}Selector = ${method.getSelector()};`);
+ console.log(`bytes4 constant ${method.getDataItem().name}SelectorGenerator = byes4(keccak256('${method.getSignature()}'));`);
+ } catch(e) {
+ _.noop();
+ }
+ });*/
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
@@ -196,23 +211,15 @@ describe.only(ContractName.CompliantForwarder, () => {
erc20Balances = await erc20Wrapper.getBalancesAsync();
});
it.only('should transfer the correct amounts when maker and taker are compliant', async () => {
-
-
- const method = new AbiEncoder.Method(compliantForwarderInstance.abi[0] as MethodAbi);
- const args = [
- compliantSignedFillOrderTx.salt,
- compliantSignedFillOrderTx.signerAddress,
- compliantSignedFillOrderTx.data,
- compliantSignedFillOrderTx.signature
- ];
- console.log(method.encode(args, {annotate: true}));
-
- await compliantForwarderInstance.executeTransaction.sendTransactionAsync(
+ const txHash = await compliantForwarderInstance.executeTransaction.sendTransactionAsync(
compliantSignedFillOrderTx.salt,
compliantSignedFillOrderTx.signerAddress,
compliantSignedFillOrderTx.data,
compliantSignedFillOrderTx.signature,
);
+ const decoder = new LogDecoder(web3Wrapper);
+ const tx = await decoder.getTxWithDecodedLogsAsync(txHash);
+ console.log(JSON.stringify(tx, null, 4));
const newBalances = await erc20Wrapper.getBalancesAsync();
const makerAssetFillAmount = takerAssetFillAmount
.times(compliantSignedOrder.makerAssetAmount)
@@ -298,7 +305,7 @@ describe.only(ContractName.CompliantForwarder, () => {
RevertReason.TakerUnverified
);
});
- it('should revert if maker address is not compliant (does not hold a Yes Token)', async () => {
+ it.only('should revert if maker address is not compliant (does not hold a Yes Token)', async () => {
// Create signed order with non-compliant maker address
const signedOrderWithBadMakerAddress = await orderFactory.newSignedOrderAsync({
senderAddress: compliantForwarderInstance.address,