pragma solidity ^0.4.24; contract BountyProxy { address impl; using BountyLibrary for BountyLibrary.Bounty; BountyLibrary.Bounty bounty; constructor(bytes32 _reference, address _issuer, uint _deadline, address _lib) public payable { impl = _lib; bounty.init(_reference, _issuer, _deadline); } function forward(bytes32 _sig, bytes _data) external payable { bytes memory data = _data; bytes4 sig = bytes4(_sig); address _impl = impl; require(_impl != address(0)); assembly { let _message := mload(0x40) //find empty memory location mstore(_message, sig) //place sig at beginning of empty storage //add _bounty mstore(add(_message, 4), sload(bounty_slot)) //add _data mstore(add(_message, 36), data) let size := returndatasize let result := delegatecall(gas, _impl, _message, msize, _output, size) //return data ?????? returndatacopy(_message, 0, size) switch result case 0 {revert(_output, size) } default { return(_output, size) } } } function getBounty() external view returns (bytes32, address, uint, uint, uint, BountyLibrary.statusOptions) { return bounty.getBounty(); } } contract BountyFactory3 { address[] public bounties; function createBounty( bytes32 _reference, uint _deadline, address _lib) external payable { address newBounty = (new BountyProxy).value(msg.value)(_reference, msg.sender, _deadline, _lib); bounties.push(newBounty); } } library BountyLibrary { //STATE VARIABLES struct Bounty { address self; bytes32 reference; address issuer; uint timestamp; uint deadline; uint reward; statusOptions status; Proposal[] proposals; } struct Proposal { bytes32 reference; address author; bool accepted; uint timestamp; } enum statusOptions {ACTIVE, COMPLETED, ABANDONED} event logSubmitProposal(bytes32 _reference); function init( Bounty storage _bounty, bytes32 _reference, address _issuer, uint _deadline ) external { require(_deadline > now, "Deadline must be a future date"); require(msg.value > 0, "Reward must be greater than 0"); _bounty.reference = _reference; _bounty.issuer = _issuer; _bounty.timestamp = now; _bounty.deadline = _deadline; _bounty.reward = msg.value; _bounty.status = statusOptions.ACTIVE; } function getBounty(Bounty storage _bounty) external view returns ( bytes32, address, uint, uint, uint, statusOptions status ) { return ( _bounty.reference, _bounty.issuer, _bounty.timestamp, _bounty.deadline, address(this).balance, _bounty.status ); } function getProposals(Bounty storage _bounty) external view returns (uint) { return _bounty.proposals.length; } function cancelBounty(Bounty storage _bounty) external { require(_bounty.issuer == msg.sender); require(_bounty.status == statusOptions.ACTIVE); require(_bounty.proposals.length < 1); _bounty.status = statusOptions.ABANDONED; } function submitProposal(Bounty storage _bounty, bytes32 _reference) external { emit logSubmitProposal(_reference); require(_bounty.issuer != msg.sender); require(_bounty.status == statusOptions.ACTIVE); Proposal memory newProposal; newProposal.reference = _reference; newProposal.author = msg.sender; newProposal.accepted = false; newProposal.timestamp = now; _bounty.proposals.push(newProposal); } function getProposal(Bounty storage _bounty, uint _id) external view returns (bytes32 reference, address author, bool accepted, uint timestamp) { return (_bounty.proposals[_id].reference, _bounty.proposals[_id].author, _bounty.proposals[_id].accepted, _bounty.proposals[_id].timestamp); } function acceptProposal(Bounty storage _bounty, uint _id) external { require(_bounty.issuer == msg.sender); require(_bounty.status == statusOptions.ACTIVE); assert(_bounty.proposals[_id].author != msg.sender); _bounty.status = statusOptions.COMPLETED; _bounty.proposals[_id].accepted = true; _bounty.proposals[_id].author.transfer(_bounty.reward); } }
0.4.18