Skip to content

Instantly share code, notes, and snippets.

@jin10086
Created April 11, 2018 07:16
Show Gist options
  • Save jin10086/68af7bebd05796a194744229a7d2467f to your computer and use it in GitHub Desktop.
Save jin10086/68af7bebd05796a194744229a7d2467f to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.21;
/// @author MinakoKojima (https://github.com/lychees)
contract SponsorToken{
address public owner;
mapping (address => bool) public admins;
struct Order {
address[] sponsors;
address issuer;
uint256 tokenId;
uint256 price;
}
Order[] private orderBook;
uint256 private orderBookSize;
function SponsorToken() public {
owner = msg.sender;
admins[owner] = true;
}
/* Modifiers */
modifier onlyOwner() {
require(owner == msg.sender);
_;
}
modifier onlyAdmins() {
require(admins[msg.sender]);
_;
}
/* Owner */
function setOwner (address _owner) onlyOwner() public {
owner = _owner;
}
function addAdmin (address _admin) onlyOwner() public {
admins[_admin] = true;
}
function removeAdmin (address _admin) onlyOwner() public {
delete admins[_admin];
}
/* Withdraw */
function withdrawAll () onlyAdmins() public {
msg.sender.transfer(address(this).balance);
}
function withdrawAmount (uint256 _amount) onlyAdmins() public {
msg.sender.transfer(_amount);
}
/* ERC721 */
function name() public pure returns (string _name) {
return "Sponsor Token";
}
/* Read */
function isAdmin(address _admin) public view returns (bool _isAdmin) {
return admins[_admin];
}
function totalOrder() public view returns (uint256 _totalOrder) {
return orderBookSize;
}
function getOrder(uint256 _id) public view returns (address[] _sponsors, address _issuer, uint256 _tokenId, uint256 _price) {
return (orderBook[_id].sponsors, orderBook[_id].issuer, orderBook[_id].tokenId, orderBook[_id].price);
}
/* Util */
function isContract(address addr) internal view returns (bool) {
uint size;
assembly { size := extcodesize(addr) } // solium-disable-line
return size > 0;
}
/* Sponsor */
function put(address _issuer, uint256 _tokenId, uint256 _price) public {
Issuer issuer = Issuer(_issuer);
require(issuer.ownerOf(_tokenId) == msg.sender);
address[] memory _sponsors;
if (orderBookSize == orderBook.length) {
orderBook.push(Order(_sponsors, _issuer, _tokenId, _price));
} else {
orderBook[orderBookSize] = Order(_sponsors, _issuer, _tokenId, _price);
}
orderBookSize += 1;
}
function sponsor(uint256 _id) public payable{
require(_id < orderBookSize);
require(msg.value >= orderBook[_id].price);
require(!isContract(msg.sender));
orderBook[_id].sponsors.push(msg.sender);
if (orderBook[_id].sponsors.length % 2 == 0){
orderBook[_id].sponsors[orderBook[_id].sponsors.length / 2].transfer(
orderBook[_id].price*98/50); // double
}
Issuer issuer = Issuer(orderBook[_id].issuer);
issuer.ownerOf(orderBook[_id].tokenId).transfer(orderBook[_id].price*1/50); // 2% Cut-off
if (msg.value > orderBook[_id].price) {
msg.sender.transfer(msg.value - orderBook[_id].price);
}
}
}
interface Issuer {
function transferFrom(address _from, address _to, uint256 _tokenId) external;
function transfer(address _to, uint256 _tokenId) external;
function ownerOf (uint256 _tokenId) external view returns (address _owner);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment