diff --git a/contracts/Vault/Connectors/ConnectorInterface.sol b/contracts/Vault/Connectors/ConnectorInterface.sol new file mode 100644 index 0000000..a78f795 --- /dev/null +++ b/contracts/Vault/Connectors/ConnectorInterface.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.4.23; + +interface ConnectorInterface { + + function register() external; + function deposit(address token, address user, uint amount) external; + function withdraw(address token, address user, uint amount) external; + function balanceOf(address token, address user) external returns (uint); + function receiver() external returns (bytes4); + +} diff --git a/contracts/Vault/VaultV2.sol b/contracts/Vault/VaultV2.sol new file mode 100644 index 0000000..e3bb377 --- /dev/null +++ b/contracts/Vault/VaultV2.sol @@ -0,0 +1,60 @@ +pragma solidity ^0.4.23; + +import "./Connectors/ConnectorInterface.sol"; + +contract VaultV2 { + + event Deposited(address token, address user, uint amount); + event Withdrawn(address token, address user, uint amount); + + mapping (bytes4 => ConnectorInterface) public receivers; + mapping (address => ConnectorInterface) public connectors; + + function () public payable { + // @todo move deposit into here potentially + + ConnectorInterface connector = receivers[msg.sig]; + require(address(connector) != 0x0); + + assembly { + calldatacopy(0x0, 0x0, calldatasize) + + result := delegatecall(sub(gas, 10000), connector, 0x0, calldatasize, 0, 0) + size := returndatasize + + returndatacopy(0, 0, size) + + switch result case 0 { revert(0, size) } + default { return(0, size) } + } + } + + function addConnector(ConnectorInterface connector) external { + connector.delegatecall(connector.register.selector); + + bytes4 receiver = connector.receiver(); + if (receiver != 0x0) { + receivers[receiver] = connector; + } + } + + function deposit(address token, address user, uint amount) external payable { + ConnectorInterface connector = connectors[token]; + connectors[token].delegatecall.value(msg.value)( + connector.deposit.selector, + token, + user, + amount + ); + + emit Deposited(token, user, amount); + } + + function withdraw(address token, address user, uint amount) external { + ConnectorInterface connector = connectors[token]; + require(connector.balanceOf(token, user) >= amount); + connector.delegatecall(connector.withdraw.selector, token, user, amount); + + emit Withdrawn(token, user, amount); + } +}