add factory and proxy contracts

This commit is contained in:
Andrea Franz 2020-02-21 20:00:48 +01:00
parent 0fa3f26f57
commit 29cdc8527f
No known key found for this signature in database
GPG Key ID: 4F0D2F2D9DE7F29D
2 changed files with 67 additions and 0 deletions

View File

@ -0,0 +1,25 @@
pragma solidity ^0.6.1;
import "./GiftBucket.sol";
import "./Proxy.sol";
contract GiftBucketFactory {
GiftBucket public GiftBucketImplementation;
event Created(address indexed gifter, address indexed bucket);
constructor() public {
GiftBucketImplementation = new GiftBucket(address(0), block.timestamp + 1);
}
function create(address _tokenAddress, uint256 _expirationTime) public returns (address) {
address p = address(new Proxy("", address(GiftBucketImplementation)));
GiftBucket g = GiftBucket(p);
g.initialize(_tokenAddress, _expirationTime, msg.sender);
emit Created(msg.sender, address(p));
return address(p);
}
}

42
contracts/Proxy.sol Normal file
View File

@ -0,0 +1,42 @@
pragma solidity ^0.6.1;
contract Proxy {
/**
* @param constructData Constructor input data for initializing the proxy
* @param contractLogic Address of the contract used as implementation logic for the proxy
*/
constructor(bytes memory constructData, address contractLogic) public {
// save the code address
assembly { // solium-disable-line
sstore(0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7, contractLogic)
}
if (constructData.length == 0) {
return;
}
(bool success,) = contractLogic.delegatecall(constructData); // solium-disable-line
require(success, "Construction failed");
}
/**
* @dev Fallback function allowing to perform a delegatecall to the given implementation.
* This function will return whatever the implementation call returns
*/
fallback() external payable {
assembly { // solium-disable-line
let contractLogic := sload(0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7)
calldatacopy(0x0, 0x0, calldatasize())
let success := delegatecall(sub(gas(), 10000), contractLogic, 0x0, calldatasize(), 0, 0)
let retSz := returndatasize()
returndatacopy(0, 0, retSz)
switch success
case 0 {
revert(0, retSz)
}
default {
return(0, retSz)
}
}
}
}