Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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 {
bytes4 sig = bytes4(_sig);
address _impl = impl;
require(_impl != address(0));
assembly {
let _message := mload(0x40) //find empty memory location
let _bounty := sload(0x0) //load bounty from storage
calldatacopy(_message, 0, 4) //place sig at beginning of empty storage
//add _bounty
mstore(add(_message, ), _bounty)
//add _data
calldatacopy(add(_message, 36), 100, sub(calldatasize,100))
let result := delegatecall(gas, _impl, _message, msize, 0, returndatasize)
//return data ??????
returndatacopy(_message, 0, returndatasize)
switch result
case 0 {revert(_message, returndatasize) }
default { return(_message, returndatasize) }
}
}
}
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}
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 {
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);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.