Nchinda Nchinda
MIT grad, ethereum developer, bitcoin user
<funny meme here>
contract Kombucha {
uint public fillAmount;
string public flavor;
constructor(string _flavor, uint _fillAmount) public {
flavor = _flavor;
fillAmount = _fillAmount;
}
function fill(uint amountToAdd) public {
....
}
function drink(uint amountToDrink) public returns (bytes32) {
...
}
}
467200 GAS
contract Kombucha {
using KombuchaLib for KombuchaLib.KombuchaStorage;
KombuchaLib.KombuchaStorage private logic;
constructor(string _flavor, uint _fillAmount, uint _capacity) public {
logic.init(_flavor, _fillAmount, _capacity);
}
function fill(uint amountToAdd) public {
return logic.fill(amountToAdd);
}
function fillAmount() public view returns (uint) {
return logic.fillAmount;
}
}
140600 GAS
contract Proxy {
address internal proxied;
address internal proxied;
constructor(address _proxied) public {
proxied = _proxied;
}
function () public payable {
address addr = proxied;
assembly {
let freememstart := mload(0x40)
calldatacopy(freememstart, 0, calldatasize())
let success := delegatecall(
not(0), addr, freememstart, calldatasize(), freememstart, 0)
switch success
case 0 { revert(freememstart, returndatasize()) }
default { return(freememstart, returndatasize()) }
}
}
}
35000 GAS
BUT BROKEN
contract Proxy is ProxyData {
address internal proxied;
address internal proxied;
constructor(address _proxied) public {
proxied = _proxied;
}
function () public payable {
address addr = proxied;
assembly {
let freememstart := mload(0x40)
calldatacopy(freememstart, 0, calldatasize())
let success := delegatecall(not(0), addr, freememstart, calldatasize(), freememstart, 0)
switch success
case 0 { revert(freememstart, returndatasize()) }
default { return(freememstart, returndatasize()) }
}
}
}
35000 GAS
contract ProxyData {
address internal proxied;
}
contract Proxy is ProxyData {
constructor(address _proxied) public {
proxied = _proxied;
}
function () public payable {
address addr = proxied;
assembly {
let freememstart := mload(0x40)
calldatacopy(freememstart, 0, calldatasize())
let success := delegatecall(not(0), addr, freememstart, calldatasize(), freememstart, 0)
switch success
case 0 { revert(freememstart, returndatasize()) }
default { return(freememstart, returndatasize()) }
}
}
}
35000 GAS
contract ProxyData { address internal proxied; } contract Proxy is ProxyData { ... }
contract Kombucha is ProxyData {
...
}
STILL BROKEN
440600 GAS vs 208063 GAS
contract ProxyData {
bytes32 internal constant IMPLEMENTATION_SLOT = keccak256("com.mtonomy.proxy.implementation");
bytes32 internal constant ADMIN_SLOT = keccak256("com.mtonomy.proxy.admin");
}
contract ProxyData {
bytes32 internal constant MANAGER_SLOT = keccak256("com.mtonomy.proxy.manager");
bytes32 internal constant IMPLEMENTATION_SLOT = keccak256("com.mtonomy.proxy.implementation");
bytes32 internal constant ADMIN_SLOT = keccak256("com.mtonomy.proxy.admin");
}
By Nchinda Nchinda