Skip to content

Instantly share code, notes, and snippets.

@tegila
Last active October 20, 2017 12:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tegila/3bc0e77c1f39c3e6389699666ceac13f to your computer and use it in GitHub Desktop.
Save tegila/3bc0e77c1f39c3e6389699666ceac13f to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.18;
// ----------------------------------------------------------------------------------------------
// BRL TOKEN EXCHANGE CONTRACT
// Enjoy. (c) tegila 2017. The MIT Licence.
// ----------------------------------------------------------------------------------------------
// ERC Token Standard #20 Interface
// https://github.com/ethereum/EIPs/issues/20
contract ERC20Interface {
// Get the total token supply
function totalSupply() constant returns (uint256 totalSupply);
// Get the account balance of another account with address _owner
function balanceOf(address _owner) constant returns (uint256 balance);
// Send _value amount of tokens to address _to
function transfer(address _to, uint256 _value) returns (bool success);
// Send _value amount of tokens from address _from to address _to
function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
// Allow _spender to withdraw from your account, multiple times, up to the _value amount.
// If this function is called again it overwrites the current allowance with _value.
// this function is required for some DEX functionality
function approve(address _spender, uint256 _value) returns (bool success);
// Returns the amount which _spender is still allowed to withdraw from _owner
function allowance(address _owner, address _spender) constant returns (uint256 remaining);
// Triggered when tokens are transferred.
event Transfer(address indexed _from, address indexed _to, uint256 _value);
// Triggered whenever approve(address _spender, uint256 _value) is called.
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
contract BRLTConsensus {
// Owner of this contract
address public owner;
// Balances for each account
mapping(address => uint256) balances;
uint256 _totalSupply = 0;
// Determina o intervalo entre os ROUNDS (em blocos)
uint32 public constant INTERVAL_BETWEEN_ROUNDS = 2000;
uint32 public constant ROUND_DURATION = 200;
// Essa taxa será cobrada sempre que alguem usar a funcao transfer
// está fixa mas meu objetivo final é transformar ela em uma curva logaritma
uint8 public constant FEES = 2; // #TODO (2% + GAS)
}
contract StandardToken is ERC20Interface, BRLTConsensus {
string public constant symbol = "BRLT";
string public constant name = "Brazilian token tied to REAL";
uint8 public constant decimals = 2;
// Owner of account approves the transfer of an amount to another account
mapping(address => mapping (address => uint256)) allowed;
// Functions with this modifier can only be executed by the owner
modifier onlyOwner() {
if (msg.sender != owner) {
throw;
}
_;
}
// Constructor
function StandardToken() {
}
function totalSupply() constant returns (uint256 totalSupply) {
totalSupply = _totalSupply;
}
// What is the balance of a particular account?
function balanceOf(address _owner) constant returns (uint256 balance) {
return balances[_owner];
}
// Transfer the balance from owner's account to another account
function transfer(address _to, uint256 _amount) returns (bool success) {
if (balances[msg.sender] >= _amount
&& _amount > 0
&& balances[_to] + _amount > balances[_to]) {
balances[msg.sender] -= _amount;
balances[_to] += _amount;
Transfer(msg.sender, _to, _amount);
return true;
} else {
return false;
}
}
// Send _value amount of tokens from address _from to address _to
// The transferFrom method is used for a withdraw workflow, allowing contracts to send
// tokens on your behalf, for example to "deposit" to a contract address and/or to charge
// fees in sub-currencies; the command should fail unless the _from account has
// deliberately authorized the sender of the message via some mechanism; we propose
// these standardized APIs for approval:
function transferFrom(
address _from,
address _to,
uint256 _amount
) returns (bool success) {
if (balances[_from] >= _amount
&& allowed[_from][msg.sender] >= _amount
&& _amount > 0
&& balances[_to] + _amount > balances[_to]) {
balances[_from] -= _amount;
allowed[_from][msg.sender] -= _amount;
balances[_to] += _amount;
Transfer(_from, _to, _amount);
return true;
} else {
return false;
}
}
// Allow _spender to withdraw from your account, multiple times, up to the _value amount.
// If this function is called again it overwrites the current allowance with _value.
function approve(address _spender, uint256 _amount) returns (bool success) {
allowed[msg.sender][_spender] = _amount;
Approval(msg.sender, _spender, _amount);
return true;
}
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
return allowed[_owner][_spender];
}
}
contract BRLT is StandardToken {
uint public collected_fees = 0;
// media *ponderada* da taxa de conversao das ofertas
// x = amount_eth
// y = amount_brlt
struct Average {
// coefficient = soma(x*y)
uint coefficient;
// denominator = soma(y)
uint denominator;
uint weighted_average;
}
Average public average;
struct Offer {
address owner;
// brlt_eth = amount_brlt / amount_eth
uint eth_brlt;
uint amount_eth;
}
Offer[] public offers;
// livro caixa
mapping(address => Offer[]) public bookkipping;
event Bid(address indexed _from, uint amount_eth, uint eth_brlt);
function bid(uint _exchange_rate) payable returns (bool success) {
// #TODO: CONFERIR SE ROUND JA COMECOU
Offer _offer;
_offer.owner = msg.sender;
_offer.amount_eth = uint(msg.value);
_offer.eth_brlt = _exchange_rate;
offers.push(_offer);
average.coefficient += _offer.amount_eth*_offer.eth_brlt;
average.denominator += _offer.amount_eth;
// #REMOVE: ENVIA DE VOLTA AO REMETENTE
_offer.owner.send(msg.value);
return true;
}
function digest() returns (bool success) {
// #TODO: CONFERIR SE ROUND JA TERMINOU
// soma (brlt - media)
uint coefficient;
average.weighted_average = average.coefficient / average.denominator;
for (uint i = 0; i < offers.length; i++) {
coefficient = (offers[i].eth_brlt - average.weighted_average)**2;
}
uint sd = sqrt((coefficient/(offers.length-1)));
for (i = 0; i < offers.length; i++) {
Offer _offer = offers[i];
// if winner
if(_offer.eth_brlt > (average.weighted_average - sd)) {
balances[_offer.owner] += (_offer.amount_eth * average.weighted_average)/(10**16);
_offer.eth_brlt = average.weighted_average;
bookkipping[_offer.owner].push(_offer);
_totalSupply += _offer.amount_eth;
}
}
return true;
}
function redeem(uint offer_number) {
// #TODO: get back my ethereum
address _owner = msg.sender;
uint amount = bookkipping[_owner][offer_number].amount_eth;
bookkipping[_owner][offer_number].amount_eth = 0;
msg.sender.send(amount);
}
function sqrt(uint x) returns (uint y) {
uint z = (x + 1) / 2;
y = x;
while (z < y) {
y = z;
z = (x / z + z) / 2;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment