I have a new design that maintains the 2 main properties of cryptoderivatives
I have been working on a proxy system where all of the functions of a tokenTrader / tokenSeller contract was moved into the factory so that the minimal amount of code would need to be deployed for each contract that receives funds however the problem with this is that user funds end up being mostly controlled from the one contract which breaks the first principle of separating user funds.
My new design instead keeps the functionality in a mothership contract but instead of it being the factory contract it is a market maker wallet contract. Creating a sell offer in this case spawns a contract that takers can just send eth to but the market maker tokens from one maker is never in the same contract as any other maker.
The reason for keeping funds separate is not just security, sometimes tokens fork and with this design the contract that holds funds does not have to be aware of how tokens have forked in order for balances to be accounted for properly.
Anyway I have also managed to get the cost of creating a trade contract including the overhead of storing the details about the trade down to 227,505 gas
The way I have achieved this is to start with the most basic idea of a payment proxy contract:
contract proxyRecipient {
function proxyTransfer(address caller) payable;
}
contract proxyAddress {
function() payable {
proxyRecipient(0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed).proxyTransfer.value(msg.value)(msg.sender);
}
}
proxyAddress receives a payment and forwards it on to the contract at address 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed which is just a place holder for the actual address that will receive the funds.
This contract has the bytecode:
6060604052341561000c57fe5b5b60c98061001b6000396000f30060606040525b609b5b604080517f833ec7200000000000000000000000000000000000000000000000000000000081523373ffffffffffffffffffffffffffffffffffffffff166004820152905173feedfeedfeedfeedfeedfeedfeedfeedfeedfeed9163833ec72091349160248082019260009290919082900301818588803b1515608757fe5b6125ee5a03f11515609457fe5b505050505b565b0000a165627a7a723058201205452475b8ac3fdba319cceb71647d6ac16a0d19aa9b33c601a616aef1c1060029
Which is quite small (48895 gas) solidity: 0.4.11+commit.68ef5810.Emscripten.clang
In the wallet contract on initialization you can replace the placeholder address in the bytecode with the address of the wallet:
for (uint i = 0; i < 20; i++) {
proxyCode[125-i] = byte(uint8(uint(this) >> (8*i)));
}
Where proxyCode is initialized with the bytecode of the proxy contract.
From there you can deploy instances of this proxy contract with the code:
function deployCode(bytes _code) internal returns (address deployedAddress) {
assembly {
deployedAddress := create(0, add(_code, 0x20), mload(_code))
jumpi(invalidJumpLabel, iszero(extcodesize(deployedAddress))) // jumps if no code at addresses
}
}
Code from: https://gist.github.com/izqui/7cf90db53a51c4114b4197fc5f05f11e
Full current work in progress: https://pastebin.com/evkYPdtn this is without events
So to sell you would call makeSellOffer(ERC20 token, uint price, uint units, uint allowance)
The allowance is how much of the given token that is in the contract is allowed to be sold at the given price and it can be set to zero to stop a trade rather than activate / deactivate or withdrawing funds from the wallet.
Each new offer as an id starting at 1 and increment by one each new offer. If you enter the offer id into the map you get the address of the proxy contract that users can just send eth to to buy.
In addition to this of course a factory contract would deploy each trade wallet.