WINGS ‐ WINGS

BokkyPooBah edited this page May 10, 2017 · 1 revision

Table of contents



Token Information



Token Contract Information



Market Making Information

Creating Your Trade Contract

If you want to list a WINGS TokenTrader contract on https://cryptoderivatives.market, use the TokenTraderFactory contract.

Execute createTradeContract(address asset, uint256 buyPrice, uint256 sellPrice, uint256 units, bool buysTokens, bool sellsTokens) to create your WINGS TokenTrader contract.

The formula for working out the buyPrice or sellPrice follows:

rate = price / units * 10^(tokenDecimals - etherDecimals)

which is:

rate = price / units * 10^(tokenDecimals - 18)

and tokenDecimals = 18, so:

rate = price / units

Watching Your Trade Contract

Find your newly created Trade contract on https://cryptoderivatives.market/tokenTraderContracts. Watch this contract address using the ABI at How To Watch A TokenTrader Contract In Ethereum Wallet / Mist.

Depositing Tokens

Use the WINGS token contract to transfer your tokens to your newly created TokenTrader address.

Depositing Ethers

Execute your TokenTrader.makerDepositEther() function, sending the amount of ethers.



How To Watch The Token Contract In Ethereum Wallet / Mist

In Ethereum Wallet / Mist, select the CONTRACTS tab and click WATCH CONTRACT to open the Watch contract window. Then:

  • Under CONTRACT NAME, enter WINGS

  • Under CONTRACT ADDRESS, enter 0x667088b212ce3d06a1b553a7221E1fD19000d9aF

  • Copy the Application Binary Interface below and paste it into the JSON INTERFACE text box

    [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"MAX_ALLOCATIONS_COUNT","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"releasePremine","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"DAYS_28","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"accountsToAllocate","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_preminer","type":"address"},{"name":"_newPreminer","type":"address"},{"name":"_newRecipient","type":"address"}],"name":"disablePreminer","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_preminer","type":"address"},{"name":"_time","type":"uint256"}],"name":"addPremineAllocation","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_preminer","type":"address"}],"name":"getPreminer","outputs":[{"name":"","type":"address"},{"name":"","type":"bool"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"},{"name":"balance","type":"uint256"}],"name":"allocate","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"multisignature","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_preminer","type":"address"},{"name":"_index","type":"uint256"}],"name":"getPreminerAllocation","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"DAYS_31","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"preminer","type":"address"},{"name":"recipient","type":"address"},{"name":"initialBalance","type":"uint256"},{"name":"monthlyPayment","type":"uint256"}],"name":"addPreminer","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"_accountsToAllocate","type":"uint256"},{"name":"_multisignature","type":"address"}],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"ALLOCATION","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":false,"name":"account","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"PREMINER_ADDED","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":false,"name":"time","type":"uint256"}],"name":"PREMINE_ALLOCATION_ADDED","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":false,"name":"timestamp","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"PREMINE_RELEASE","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"oldPreminer","type":"address"},{"indexed":false,"name":"newPreminer","type":"address"},{"indexed":false,"name":"newRecipient","type":"address"}],"name":"PREMINER_CHANGED","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]

  • Click OK



How To Watch The Token In Ethereum Wallet / Mist

In Ethereum Wallet / Mist, select the CONTRACTS tab and click WATCH TOKEN to open the Add token window. Then:

  • Under TOKEN CONTRACT ADDRESS, enter 0x667088b212ce3d06a1b553a7221E1fD19000d9aF. The additional fields should automatically be filled in.

  • Click OK



The Token Contract Source Code

The verified source code can be found at 0x667088b212ce3d06a1b553a7221E1fD19000d9aF and follows:

contract Ownable {
  address public owner;

  function Ownable() {
    owner = msg.sender;
  }

  modifier onlyOwner() {
    if (msg.sender == owner)
      _;
  }

  function transferOwner(address newOwner) onlyOwner {
    if (newOwner != address(0)) owner = newOwner;
  }

}

contract ERC20 {
  uint public totalSupply;
  function balanceOf(address who) constant returns (uint);
  function allowance(address owner, address spender) constant returns (uint);

  function transfer(address to, uint value) returns (bool ok);
  function transferFrom(address from, address to, uint value) returns (bool ok);
  function approve(address spender, uint value) returns (bool ok);
  event Transfer(address indexed from, address indexed to, uint value);
  event Approval(address indexed owner, address indexed spender, uint value);
}

contract SafeMath {
  function safeMul(uint a, uint b) internal returns (uint) {
    uint c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function safeSub(uint a, uint b) internal returns (uint) {
    assert(b <= a);
    return a - b;
  }

  function safeAdd(uint a, uint b) internal returns (uint) {
    uint c = a + b;
    assert(c>=a && c>=b);
    return c;
  }

  function assert(bool assertion) internal {
    if (!assertion) throw;
  }
}

contract StandardToken is ERC20, SafeMath {

  mapping(address => uint) balances;
  mapping (address => mapping (address => uint)) allowed;

  function transfer(address _to, uint _value) returns (bool success) {
    balances[msg.sender] = safeSub(balances[msg.sender], _value);
    balances[_to] = safeAdd(balances[_to], _value);
    Transfer(msg.sender, _to, _value);
    return true;
  }

  function transferFrom(address _from, address _to, uint _value) returns (bool success) {
    var _allowance = allowed[_from][msg.sender];
    
    balances[_to] = safeAdd(balances[_to], _value);
    balances[_from] = safeSub(balances[_from], _value);
    allowed[_from][msg.sender] = safeSub(_allowance, _value);
    Transfer(_from, _to, _value);
    return true;
  }

  function balanceOf(address _owner) constant returns (uint balance) {
    return balances[_owner];
  }

  function approve(address _spender, uint _value) returns (bool success) {
    allowed[msg.sender][_spender] = _value;
    Approval(msg.sender, _spender, _value);
    return true;
  }

  function allowance(address _owner, address _spender) constant returns (uint remaining) {
    return allowed[_owner][_spender];
  }

}

/*
  Wings ERC20 Token.
  Added allocation for users who participiated in Wings Campaign.

  Important!
  We have to run pre-mine allocation first.
  And only then rest of users.
  Or it's not going to work due to whenAllocation logic.
*/
contract Token is StandardToken, Ownable {
  // Account allocation event
  event ALLOCATION(address indexed account, uint amount);

  /*
    Premine events
  */
  event PREMINER_ADDED(address indexed owner, address account, uint amount);
  event PREMINE_ALLOCATION_ADDED(address indexed account, uint time);
  event PREMINE_RELEASE(address indexed account, uint timestamp, uint amount);
  event PREMINER_CHANGED(address indexed oldPreminer, address newPreminer, address newRecipient);

  /*
    Premine structure
  */
  struct Preminer {
    address account;
    uint monthlyPayment;
    uint latestAllocation;
    bool disabled;

    uint allocationsCount;
    mapping(uint => uint) allocations;
  }

  /*
    List of preminers
  */
  mapping(address => Preminer) preminers;

  /*
    Token Name & Token Symbol & Decimals
  */
  string public name = "WINGS";
  string public symbol = "WINGS";
  uint public decimals = 18;

  /*
    Total supply
  */
  uint public totalSupply = 10**26;//100000000000000000000000000;

  /*
    Premine allocation interval
  */
  uint public DAYS_28 = 2419200;
  uint public DAYS_31 = 2678400;

  /*
    Maximum premine allocations count
  */
  uint public MAX_ALLOCATIONS_COUNT = 26;

  /*
    How many accounts allocated?
  */
  uint public accountsToAllocate;

  /*
    Multisignature
  */
  address public multisignature;

  /*
    Only multisignature
  */
  modifier onlyMultisignature() {
    if (msg.sender != multisignature) {
      throw;
    }

    _;
  }

  /*
    When preminer is not disabled
  */
  modifier whenPreminerIsntDisabled(address _account) {
    if (preminers[_account].disabled == true) {
      throw;
    }

    _;
  }

  /*
    Modifier for checking is allocation completed.
    Maybe we should add here pre-mine accounts too.
  */
  modifier whenAllocation(bool value) {
    if ((accountsToAllocate > 0) == value) {
      _;
    } else {
      throw;
    }
  }

  /*
    Check if user already allocated
  */
  modifier whenAccountHasntAllocated(address user) {
    if (balances[user] == 0) {
      _;
    } else {
      throw;
    }
  }

  /*
    Check if preminer already added
  */
  modifier whenPremineHasntAllocated(address preminer) {
    if (preminers[preminer].account == address(0)) {
      _;
    } else {
      throw;
    }
  }

  function Token(uint _accountsToAllocate, address _multisignature) {
    /*
      Maybe we should calculate it in allocation and pre-mine.
      I mean total supply
    */
    owner = msg.sender;
    accountsToAllocate = _accountsToAllocate;
    multisignature = _multisignature;
  }

  /*
    Allocate tokens for users.
    Only owner and only while allocation active.

    Should check if user allocated already (no double allocations)
  */
  function allocate(address user, uint balance) onlyOwner() whenAllocation(true) whenAccountHasntAllocated(user) {
    balances[user] = balance;

    accountsToAllocate--;
    ALLOCATION(user, balance);
  }

  /*
    Standard Token functional
  */
  function transfer(address _to, uint _value) whenAllocation(false) returns (bool success) {
    return super.transfer(_to, _value);
  }

  function transferFrom(address _from, address _to, uint _value) whenAllocation(false) returns (bool success) {
    return super.transferFrom(_from, _to, _value);
  }

  function approve(address _spender, uint _value) whenAllocation(false) returns (bool success) {
    return super.approve(_spender, _value);
  }

  /*
    Premine functionality
  */

  /*
    Add pre-mine account
  */
  function addPreminer(address preminer, address recipient, uint initialBalance, uint monthlyPayment) onlyOwner() whenAllocation(true) whenPremineHasntAllocated(preminer) {
    var premine = Preminer(
        recipient,
        monthlyPayment,
        0,
        false,
        0
      );


    balances[recipient] = safeAdd(balances[recipient], initialBalance);
    preminers[preminer] = premine;
    accountsToAllocate--;
    PREMINER_ADDED(preminer, premine.account, initialBalance);
  }

  /*
    Disable pre-miner
  */
  function disablePreminer(address _preminer, address _newPreminer, address _newRecipient) onlyMultisignature() whenPreminerIsntDisabled(_preminer) {
    var oldPreminer = preminers[_preminer];

    if (oldPreminer.account == address(0) || preminers[_newPreminer].account != address(0)) {
      throw;
    }

    preminers[_newPreminer] = oldPreminer;
    preminers[_newPreminer].account = _newRecipient;
    oldPreminer.disabled = true;

    if(preminers[_newPreminer].disabled == true) {
      throw;
    }

    for (uint i = 0; i < preminers[_newPreminer].allocationsCount; i++) {
      preminers[_newPreminer].allocations[i] = oldPreminer.allocations[i];
    }

    PREMINER_CHANGED(_preminer, _newPreminer, _newRecipient);
  }

  /*
    Add pre-mine allocation
  */
  function addPremineAllocation(address _preminer, uint _time) onlyOwner() whenAllocation(true) whenPreminerIsntDisabled(_preminer) {
    var preminer = preminers[_preminer];

    if (preminer.account == address(0) ||  _time == 0 || preminer.allocationsCount == MAX_ALLOCATIONS_COUNT) {
      throw;
    }

    if (preminer.allocationsCount > 0) {
      var previousAllocation = preminer.allocations[preminer.allocationsCount-1];

      if (previousAllocation > _time) {
        throw;
      }

      if (previousAllocation + DAYS_28 > _time) {
        throw;
      }

      if (previousAllocation + DAYS_31 < _time) {
        throw;
      }
    }

    preminer.allocations[preminer.allocationsCount++] = _time;
    PREMINE_ALLOCATION_ADDED(_preminer, _time);
  }

  /*
    Get preminer
  */
  function getPreminer(address _preminer) constant returns (address, bool, uint, uint, uint) {
    var preminer = preminers[_preminer];

    return (preminer.account, preminer.disabled, preminer.monthlyPayment, preminer.latestAllocation, preminer.allocationsCount);
  }

  /*
    Get preminer allocation time by index
  */
  function getPreminerAllocation(address _preminer, uint _index) constant returns (uint) {
    return preminers[_preminer].allocations[_index];
  }

  /*
    Release premine when preminer asking
    Gas usage: 0x5786 or 22406 GAS.
    Maximum is 26 months of pre-mine in case of Wings. So should be enough to execute it.
  */
  function releasePremine() whenAllocation(false) whenPreminerIsntDisabled(msg.sender) {
    var preminer = preminers[msg.sender];

    if (preminer.account == address(0)) {
      throw;
    }

    for (uint i = preminer.latestAllocation; i < preminer.allocationsCount; i++) {
      if (preminer.allocations[i] < block.timestamp) {
        if (preminer.allocations[i] == 0) {
          continue;
        }

        balances[preminer.account] = safeAdd(balances[preminer.account], preminer.monthlyPayment);
        preminer.latestAllocation = i;

        PREMINE_RELEASE(preminer.account, preminer.allocations[i], preminer.monthlyPayment);
        preminer.allocations[i] = 0;
      } else {
        break;
      }
    }
  }
}
Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.