Include Embark and .sol contracts

This commit is contained in:
Andy Tudhope 2019-04-08 16:46:14 +02:00
parent c8b4b29408
commit 38928ead32
No known key found for this signature in database
GPG Key ID: 02A3DFA93BF26AD2
25 changed files with 5655 additions and 1303 deletions

9
.gitignore vendored
View File

@ -1,3 +1,11 @@
.embark
chains.json
config/livenet/password
config/production/password
coverage
embarkArtifacts
node_modules
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# Editor artifacts
@ -26,3 +34,4 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*

0
.npmrc Normal file
View File

150
config/blockchain.js Normal file
View File

@ -0,0 +1,150 @@
module.exports = {
// applies to all environments
default: {
enabled: true,
rpcHost: "localhost", // HTTP-RPC server listening interface (default: "localhost")
rpcPort: 8545, // HTTP-RPC server listening port (default: 8545)
rpcCorsDomain: { // Domains from which to accept cross origin requests (browser enforced). This can also be a comma separated list
auto: true, // When "auto" is true, Embark will automatically set the cors to the address of the webserver
additionalCors: [] // Additional CORS domains to add to the list. If "auto" is false, only those will be added
},
wsRPC: true, // Enable the WS-RPC server
wsOrigins: { // Same thing as "rpcCorsDomain", but for WS origins
auto: true,
additionalCors: []
},
wsHost: "localhost", // WS-RPC server listening interface (default: "localhost")
wsPort: 8546 // WS-RPC server listening port (default: 8546)
// Accounts to use as node accounts
// The order here corresponds to the order of `web3.eth.getAccounts`, so the first one is the `defaultAccount`
/*,accounts: [
{
nodeAccounts: true, // Accounts use for the node
numAddresses: "1", // Number of addresses/accounts (defaults to 1)
password: "config/development/devpassword" // Password file for the accounts
},
// Below are additional accounts that will count as `nodeAccounts` in the `deployment` section of your contract config
// Those will not be unlocked in the node itself
{
privateKey: "your_private_key"
},
{
privateKeyFile: "path/to/file", // Either a keystore or a list of keys, separated by , or ;
password: "passwordForTheKeystore" // Needed to decrypt the keystore file
},
{
mnemonic: "12 word mnemonic",
addressIndex: "0", // Optional. The index to start getting the address
numAddresses: "1", // Optional. The number of addresses to get
hdpath: "m/44'/60'/0'/0/" // Optional. HD derivation path
}
]*/
},
// default environment, merges with the settings in default
// assumed to be the intended environment by `embark run` and `embark blockchain`
development: {
ethereumClientName: "geth", // Can be geth or parity (default:geth)
//ethereumClientBin: "geth", // path to the client binary. Useful if it is not in the global PATH
networkType: "custom", // Can be: testnet, rinkeby, livenet or custom, in which case, it will use the specified networkId
networkId: 1337, // Network id used when networkType is custom
isDev: true, // Uses and ephemeral proof-of-authority network with a pre-funded developer account, mining enabled
datadir: ".embark/development/datadir", // Data directory for the databases and keystore (Geth 1.8.15 and Parity 2.0.4 can use the same base folder, till now they does not conflict with each other)
mineWhenNeeded: true, // Uses our custom script (if isDev is false) to mine only when needed
nodiscover: true, // Disables the peer discovery mechanism (manual peer addition)
maxpeers: 0, // Maximum number of network peers (network disabled if set to 0) (default: 25)
proxy: true, // Proxy is used to present meaningful information about transactions
targetGasLimit: 9000000, // Target gas limit sets the artificial target gas floor for the blocks to mine
simulatorBlocktime: 0 // Specify blockTime in seconds for automatic mining. Default is 0 and no auto-mining.
},
// merges with the settings in default
// used with "embark run privatenet" and/or "embark blockchain privatenet"
privatenet: {
networkType: "custom",
networkId: 1337,
isDev: false,
datadir: ".embark/privatenet/datadir",
// -- mineWhenNeeded --
// This options is only valid when isDev is false.
// Enabling this option uses our custom script to mine only when needed.
// Embark creates a development account for you (using `geth account new`) and funds the account. This account can be used for
// development (and even imported in to MetaMask). To enable correct usage, a password for this account must be specified
// in the `account > password` setting below.
// NOTE: once `mineWhenNeeded` is enabled, you must run an `embark reset` on your dApp before running
// `embark blockchain` or `embark run` for the first time.
mineWhenNeeded: true,
// -- genesisBlock --
// This option is only valid when mineWhenNeeded is true (which is only valid if isDev is false).
// When enabled, geth uses POW to mine transactions as it would normally, instead of using POA as it does in --dev mode.
// On the first `embark blockchain or embark run` after this option is enabled, geth will create a new chain with a
// genesis block, which can be configured using the `genesisBlock` configuration option below.
genesisBlock: "config/privatenet/genesis.json", // Genesis block to initiate on first creation of a development node
nodiscover: true,
maxpeers: 0,
proxy: true,
accounts: [
{
nodeAccounts: true,
password: "config/privatenet/password" // Password to unlock the account
}
],
targetGasLimit: 8000000,
simulatorBlocktime: 0
},
privateparitynet: {
ethereumClientName: "parity",
networkType: "custom",
networkId: 1337,
isDev: false,
genesisBlock: "config/privatenet/genesis-parity.json", // Genesis block to initiate on first creation of a development node
datadir: ".embark/privatenet/datadir",
mineWhenNeeded: false,
nodiscover: true,
maxpeers: 0,
proxy: true,
accounts: [
{
nodeAccounts: true,
password: "config/privatenet/password"
}
],
targetGasLimit: 8000000,
simulatorBlocktime: 0
},
// merges with the settings in default
// used with "embark run testnet" and/or "embark blockchain testnet"
testnet: {
networkType: "testnet",
syncMode: "light",
accounts: [
{
nodeAccounts: true,
password: "config/testnet/password"
}
]
},
// merges with the settings in default
// used with "embark run livenet" and/or "embark blockchain livenet"
livenet: {
networkType: "livenet",
syncMode: "light",
rpcCorsDomain: "http://localhost:8000",
wsOrigins: "http://localhost:8000",
accounts: [
{
nodeAccounts: true,
password: "config/livenet/password"
}
]
}
// you can name an environment with specific settings and then specify with
// "embark run custom_name" or "embark blockchain custom_name"
//custom_name: {
//}
};

46
config/communication.js Normal file
View File

@ -0,0 +1,46 @@
module.exports = {
// default applies to all environments
default: {
enabled: true,
provider: "whisper", // Communication provider. Currently, Embark only supports whisper
available_providers: ["whisper"], // Array of available providers
},
// default environment, merges with the settings in default
// assumed to be the intended environment by `embark run`
development: {
connection: {
host: "localhost", // Host of the blockchain node
port: 8546, // Port of the blockchain node
type: "ws" // Type of connection (ws or rpc)
}
},
// merges with the settings in default
// used with "embark run privatenet"
privatenet: {
},
// merges with the settings in default
// used with "embark run testnet"
testnet: {
},
// merges with the settings in default
// used with "embark run livenet"
livenet: {
},
// you can name an environment with specific settings and then specify with
// "embark run custom_name"
//custom_name: {
//}
// Use this section when you need a specific symmetric or private keys in whisper
/*
,keys: {
symmetricKey: "your_symmetric_key",// Symmetric key for message decryption
privateKey: "your_private_key" // Private Key to be used as a signing key and for message decryption
}
*/
//}
};

91
config/contracts.js Normal file
View File

@ -0,0 +1,91 @@
module.exports = {
// default applies to all environments
default: {
// Blockchain node to deploy the contracts
deployment: {
host: "localhost", // Host of the blockchain node
port: 8546, // Port of the blockchain node
type: "ws" // Type of connection (ws or rpc),
// Accounts to use instead of the default account to populate your wallet
// The order here corresponds to the order of `web3.eth.getAccounts`, so the first one is the `defaultAccount`
/*,accounts: [
{
privateKey: "your_private_key",
balance: "5 ether" // You can set the balance of the account in the dev environment
// Balances are in Wei, but you can specify the unit with its name
},
{
privateKeyFile: "path/to/file", // Either a keystore or a list of keys, separated by , or ;
password: "passwordForTheKeystore" // Needed to decrypt the keystore file
},
{
mnemonic: "12 word mnemonic",
addressIndex: "0", // Optional. The index to start getting the address
numAddresses: "1", // Optional. The number of addresses to get
hdpath: "m/44'/60'/0'/0/" // Optional. HD derivation path
},
{
"nodeAccounts": true // Uses the Ethereum node's accounts
}
]*/
},
// order of connections the dapp should connect to
dappConnection: [
"$WEB3", // uses pre existing web3 object if available (e.g in Mist)
"ws://localhost:8546",
"http://localhost:8545"
],
// Automatically call `ethereum.enable` if true.
// If false, the following code must run before sending any transaction: `await EmbarkJS.enableEthereum();`
// Default value is true.
// dappAutoEnable: true,
gas: "auto",
// Strategy for the deployment of the contracts:
// - implicit will try to deploy all the contracts located inside the contracts directory
// or the directory configured for the location of the contracts. This is default one
// when not specified
// - explicit will only attempt to deploy the contracts that are explicitly specified inside the
// contracts section.
//strategy: 'implicit',
contracts: {
DAppStore: {
args: [ 0x744d70fdbe2ba4cf95131626614a1763df805b9e ]
}
}
},
// default environment, merges with the settings in default
// assumed to be the intended environment by `embark run`
development: {
dappConnection: [
"ws://localhost:8546",
"http://localhost:8545",
"$WEB3" // uses pre existing web3 object if available (e.g in Mist)
]
},
// merges with the settings in default
// used with "embark run privatenet"
privatenet: {
},
// merges with the settings in default
// used with "embark run testnet"
testnet: {
},
// merges with the settings in default
// used with "embark run livenet"
livenet: {
},
// you can name an environment with specific settings and then specify with
// "embark run custom_name" or "embark blockchain custom_name"
//custom_name: {
//}
};

View File

@ -0,0 +1 @@
dev_password

39
config/namesystem.js Normal file
View File

@ -0,0 +1,39 @@
module.exports = {
// default applies to all environments
default: {
enabled: true,
available_providers: ["ens"],
provider: "ens"
},
// default environment, merges with the settings in default
// assumed to be the intended environment by `embark run`
development: {
register: {
rootDomain: "embark.eth",
subdomains: {
'status': '0x1a2f3b98e434c02363f3dac3174af93c1d690914'
}
}
},
// merges with the settings in default
// used with "embark run privatenet"
privatenet: {
},
// merges with the settings in default
// used with "embark run testnet"
testnet: {
},
// merges with the settings in default
// used with "embark run livenet"
livenet: {
},
// you can name an environment with specific settings and then specify with
// "embark run custom_name" or "embark blockchain custom_name"
//custom_name: {
//}
};

27
config/pipeline.js Normal file
View File

@ -0,0 +1,27 @@
// Embark has support for Flow enabled by default in its built-in webpack
// config: type annotations will automatically be stripped out of DApp sources
// without any additional configuration. Note that type checking is not
// performed during builds.
// To enable Flow type checking refer to the preconfigured template:
// https://github.com/embark-framework/embark-flow-template
// A new DApp can be created from that template with:
// embark new --template flow
module.exports = {
typescript: false,
// Setting `typescript: true` in this config will disable Flow support in
// Embark's default webpack config and enable TypeScript support: .ts and
// .tsx sources will automatically be transpiled into JavaScript without any
// additional configuration. Note that type checking is not performed during
// builds.
// To enable TypeScript type checking refer to the preconfigured template:
// https://github.com/embark-framework/embark-typescript-template
// A new DApp can be created from that template with:
// embark new --template typescript
enabled: true
// Setting `enabled: false` in this config will disable Embark's built-in Webpack
// pipeline. The developer will need to use a different frontend build tool, such as
// `create-react-app` or Angular CLI to build their dapp
};

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,20 @@
{
"config": {
"homesteadBlock": 0,
"byzantiumBlock": 0,
"eip155Block": 0,
"eip158Block": 0,
"daoForkSupport": true
},
"nonce": "0x0000000000000042",
"difficulty": "0x0",
"alloc": {
"0x3333333333333333333333333333333333333333": {"balance": "15000000000000000000"}
},
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x3333333333333333333333333333333333333333",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x7a1200"
}

View File

@ -0,0 +1 @@
dev_password

59
config/storage.js Normal file
View File

@ -0,0 +1,59 @@
module.exports = {
// default applies to all environments
default: {
enabled: true,
ipfs_bin: "ipfs",
available_providers: ["ipfs"],
upload: {
provider: "ipfs",
host: "localhost",
port: 5001
},
dappConnection: [
{
provider: "ipfs",
host: "localhost",
port: 5001,
getUrl: "http://localhost:8080/ipfs/"
}
]
// Configuration to start Swarm in the same terminal as `embark run`
/*,account: {
address: "YOUR_ACCOUNT_ADDRESS", // Address of account accessing Swarm
password: "PATH/TO/PASSWORD/FILE" // File containing the password of the account
},
swarmPath: "PATH/TO/SWARM/EXECUTABLE" // Path to swarm executable (default: swarm)*/
},
// default environment, merges with the settings in default
// assumed to be the intended environment by `embark run`
development: {
enabled: true,
upload: {
provider: "ipfs",
host: "localhost",
port: 5001,
getUrl: "http://localhost:8080/ipfs/"
}
},
// merges with the settings in default
// used with "embark run privatenet"
privatenet: {
},
// merges with the settings in default
// used with "embark run testnet"
testnet: {
},
// merges with the settings in default
// used with "embark run livenet"
livenet: {
},
// you can name an environment with specific settings and then specify with
// "embark run custom_name"
//custom_name: {
//}
};

1
config/testnet/password Normal file
View File

@ -0,0 +1 @@
test_password

6
config/webserver.js Normal file
View File

@ -0,0 +1,6 @@
module.exports = {
enabled: true,
host: "localhost",
openBrowser: true,
port: 8000
};

0
contracts/.gitkeep Normal file
View File

305
contracts/DAppStore.sol Normal file
View File

@ -0,0 +1,305 @@
pragma solidity ^0.5.1;
import "./token/MiniMeTokenInterface.sol";
import "./token/ApproveAndCallFallBack.sol";
import "./utils/SafeMath.sol";
import "./utils/BancorFormula.sol";
contract DAppStore is ApproveAndCallFallBack, BancorFormula {
using SafeMath for uint;
// Could be any EIP20/MiniMe token
MiniMeTokenInterface SNT;
// Total SNT in circulation
uint total;
// Parameter to calculate Max SNT any one DApp can stake
uint ceiling;
// The max amount of tokens it is possible to stake, as a percentage of the total in circulation
uint max;
// Decimal precision for this contract
uint decimals;
// Prevents overflows in votes_minted
uint safeMax;
// Whether we need more than an id param to identify arbitrary data must still be discussed.
struct Data {
address developer;
bytes32 id;
uint balance;
uint rate;
uint available;
uint votes_minted;
uint votes_cast;
uint effective_balance;
}
Data[] public dapps;
mapping(bytes32 => uint) public id2index;
event DAppCreated(bytes32 indexed id, uint votes_mint, uint amount);
event Upvote(bytes32 indexed id, uint newEffectiveBalance);
event Downvote(bytes32 indexed id, uint newEffectiveBalance);
event Withdraw(bytes32 indexed id, uint newEffectiveBalance);
constructor(MiniMeTokenInterface _SNT) public {
SNT = _SNT;
total = 3470483788;
ceiling = 588; // 2 dec fixed pos, ie: 5 == 0.05, 588 == 5.88,
decimals = 1000000;
max = (total * ceiling) / decimals; // 4 decimal points for %, 2 because we only use 1/100th of total in circulation
safeMax = 98 * max / 100;
}
/**
* @dev Anyone can create a DApp (i.e an arb piece of data this contract happens to care about).
* @param _id bytes32 unique identifier.
* @param _amount of tokens to stake on initial ranking.
*/
function createDApp(bytes32 _id, uint _amount) public {
_createDApp(msg.sender, _id, _amount);
}
function _createDApp(address _from, bytes32 _id, uint _amount) internal {
require(_amount > 0, "You must spend some SNT to submit a ranking in order to avoid spam");
require (_amount < safeMax, "You cannot stake more SNT than the ceiling dictates");
require(SNT.allowance(_from, address(this)) >= _amount, "Not enough SNT allowance");
require(SNT.transferFrom(_from, address(this), _amount), "Transfer failed");
uint dappIdx = dapps.length;
dapps.length++;
Data storage d = dapps[dappIdx];
d.developer = msg.sender;
d.id = _id;
uint precision;
uint result;
d.balance = _amount;
d.rate = decimals - (d.balance * decimals/max);
d.available = d.balance * d.rate;
(result, precision) = BancorFormula.power(d.available, decimals, uint32(decimals), uint32(d.rate));
d.votes_minted = result >> precision;
d.votes_cast = 0;
d.effective_balance = _amount;
id2index[_id] = dappIdx;
emit DAppCreated(_id, d.votes_minted, d.effective_balance);
}
/**
* @dev Used in UI to display effect on ranking of user's donation
* @param _id bytes32 unique identifier.
* @param _amount of tokens to stake/"donate" to this DApp's ranking.
* @return effect of donation on DApp's effective_balance
*/
function upvoteEffect(bytes32 _id, uint _amount) public view returns(uint effect) {
uint dappIdx = id2index[_id];
Data memory d = dapps[dappIdx];
require(d.id == _id, "Error fetching correct data");
require(d.balance + _amount < safeMax, "You cannot upvote by this much, try with a lower amount");
uint precision;
uint result;
uint mBalance = d.balance + _amount;
uint mRate = decimals - (mBalance * decimals/max);
uint mAvailable = mBalance * mRate;
(result, precision) = BancorFormula.power(mAvailable, decimals, uint32(decimals), uint32(mRate));
uint mVMinted = result >> precision;
uint mEBalance = mBalance - ((mVMinted*mRate)*(mAvailable/mVMinted));
return (mEBalance - d.effective_balance);
}
/**
* @dev Sends SNT directly to the contract, not the developer. This gets added to the DApp's balance, no curve required.
* @param _id bytes32 unique identifier.
* @param _amount of tokens to stake on DApp's ranking. Used for upvoting + staking more.
*/
function upvote(bytes32 _id, uint _amount) public {
_upvote(msg.sender, _id, _amount);
}
function _upvote(address _from, bytes32 _id, uint _amount) internal {
require(_amount > 0, "You must send some SNT in order to upvote");
uint dappIdx = id2index[_id];
Data storage d = dapps[dappIdx];
require(d.id == _id, "Error fetching correct data");
require(d.balance + _amount < safeMax, "You cannot upvote by this much, try with a lower amount");
require(SNT.allowance(_from, address(this)) >= _amount, "Not enough SNT allowance");
require(SNT.transferFrom(_from, address(this), _amount), "Transfer failed");
uint precision;
uint result;
d.balance = d.balance + _amount;
d.rate = decimals - (d.balance * decimals/max);
d.available = d.balance * d.rate;
(result, precision) = BancorFormula.power(d.available, decimals, uint32(decimals), uint32(d.rate));
d.votes_minted = result >> precision;
d.effective_balance = d.balance - ((d.votes_cast*d.rate)*(d.available/d.votes_minted));
emit Upvote(_id, d.effective_balance);
}
/**
* @dev Downvotes always remove 1% of the current ranking.
* @param _id bytes32 unique identifier.
* @return cost
*/
function downvoteCost(bytes32 _id) public view returns(uint b, uint v_r, uint c) {
uint dappIdx = id2index[_id];
Data memory d = dapps[dappIdx];
require(d.id == _id, "Error fetching correct data");
uint balance_down_by = (d.effective_balance / 100);
uint votes_required = (balance_down_by * d.votes_minted * d.rate) / d.available;
uint cost = (d.available / (d.votes_minted - (d.votes_cast + votes_required))) * (votes_required / 1 / 10000);
return (balance_down_by, votes_required, cost);
}
/**
* @dev Sends SNT directly to the developer and lower the DApp's effective balance by 1%
* @param _id bytes32 unique identifier.
*/
function downvote(bytes32 _id) public {
_downvote(msg.sender, _id);
}
function _downvote(address _from, bytes32 _id) internal {
uint dappIdx = id2index[_id];
Data storage d = dapps[dappIdx];
require(d.id == _id, "Error fetching correct data");
(uint b, uint v_r, uint c) = downvoteCost(_id);
require(SNT.allowance(_from, d.developer) >= c, "Not enough SNT allowance");
require(SNT.transferFrom(_from, d.developer, c), "Transfer failed");
d.available = d.available - c;
d.votes_cast = d.votes_cast + v_r;
d.effective_balance = d.effective_balance - b;
emit Downvote(_id, d.effective_balance);
}
/**
* @dev Developers can withdraw an amount not more than what was available of the
SNT they originally staked minus what they have already received back in downvotes.
* @param _id bytes32 unique identifier.
* @param _amount of tokens to withdraw from DApp's overall balance.
*/
function withdraw(bytes32 _id, uint _amount) public {
uint dappIdx = id2index[_id];
Data storage d = dapps[dappIdx];
require(d.id == _id, "Error fetching correct data");
require(msg.sender == d.developer, "Only the developer can withdraw SNT staked on this data");
require(_amount <= d.available, "You can only withdraw a percentage of the SNT staked, less what you have already received");
uint precision;
uint result;
d.balance = d.balance - _amount;
d.rate = decimals - (d.balance * decimals/max);
d.available = d.balance * d.rate;
(result, precision) = BancorFormula.power(d.available, decimals, uint32(decimals), uint32(d.rate));
d.votes_minted = result >> precision;
if (d.votes_cast > d.votes_minted) {
d.votes_cast = d.votes_minted;
}
d.effective_balance = d.balance - ((d.votes_cast*d.rate)*(d.available/d.votes_minted));
SNT.transferFrom(address(this), d.developer, _amount);
emit Withdraw(_id, d.effective_balance);
}
/**
* @notice Support for "approveAndCall".
* @param _from Who approved.
* @param _amount Amount being approved, needs to be equal `_amount` or `cost`.
* @param _token Token being approved, needs to be `SNT`.
* @param _data Abi encoded data with selector of `register(bytes32,address,bytes32,bytes32)`.
*/
function receiveApproval(
address _from,
uint256 _amount,
address _token,
bytes memory _data
)
public
{
require(_token == address(SNT), "Wrong token");
require(_token == address(msg.sender), "Wrong account");
require(_data.length <= 132, "Incorrect data");
bytes4 sig;
bytes32 id;
uint256 amount;
(sig, id, amount) = abiDecodeRegister(_data);
require(_amount == amount, "Wrong amount");
// TODO: check these function sigs!
if(sig == bytes4(0xe4bb1695)) {
_createDApp(_from, id, amount);
} else if(sig == bytes4(0xfaa5fd03)) {
_downvote(_from, id);
} else if(sig == bytes4(0x0643e21b)) {
_upvote(_from, id, amount);
} else {
revert("Wrong method selector");
}
}
/**
* @dev Decodes abi encoded data with selector for "functionName(bytes32,uint256)".
* @param _data Abi encoded data.
* @return Decoded registry call.
*/
function abiDecodeRegister(
bytes memory _data
)
private
pure
returns(
bytes4 sig,
bytes32 id,
uint256 amount
)
{
assembly {
sig := mload(add(_data, add(0x20, 0)))
id := mload(add(_data, 36))
amount := mload(add(_data, 68))
}
}
}

View File

@ -0,0 +1,5 @@
pragma solidity ^0.5.1;
contract ApproveAndCallFallBack {
function receiveApproval(address from, uint256 _amount, address _token, bytes memory _data) public;
}

View File

@ -0,0 +1,53 @@
pragma solidity ^0.5.1;
// Abstract contract for the full ERC 20 Token standard
// https://github.com/ethereum/EIPs/issues/20
interface ERC20Token {
/**
* @notice send `_value` token to `_to` from `msg.sender`
* @param _to The address of the recipient
* @param _value The amount of token to be transferred
* @return Whether the transfer was successful or not
*/
function transfer(address _to, uint256 _value) external returns (bool success);
/**
* @notice `msg.sender` approves `_spender` to spend `_value` tokens
* @param _spender The address of the account able to transfer the tokens
* @param _value The amount of tokens to be approved for transfer
* @return Whether the approval was successful or not
*/
function approve(address _spender, uint256 _value) external returns (bool success);
/**
* @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
* @param _from The address of the sender
* @param _to The address of the recipient
* @param _value The amount of token to be transferred
* @return Whether the transfer was successful or not
*/
function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);
/**
* @param _owner The address from which the balance will be retrieved
* @return The balance
*/
function balanceOf(address _owner) external view returns (uint256 balance);
/**
* @param _owner The address of the account owning tokens
* @param _spender The address of the account able to transfer the tokens
* @return Amount of remaining tokens allowed to spent
*/
function allowance(address _owner, address _spender) external view returns (uint256 remaining);
/**
* @notice return total supply of tokens
*/
function totalSupply() external view returns (uint256 supply);
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}

View File

@ -0,0 +1,108 @@
pragma solidity ^0.5.1;
import "./ERC20Token.sol";
contract MiniMeTokenInterface is ERC20Token {
/**
* @notice `msg.sender` approves `_spender` to send `_amount` tokens on
* its behalf, and then a function is triggered in the contract that is
* being approved, `_spender`. This allows users to use their tokens to
* interact with contracts in one function call instead of two
* @param _spender The address of the contract able to transfer the tokens
* @param _amount The amount of tokens to be approved for transfer
* @return True if the function call was successful
*/
function approveAndCall(
address _spender,
uint256 _amount,
bytes calldata _extraData
)
external
returns (bool success);
/**
* @notice Creates a new clone token with the initial distribution being
* this token at `_snapshotBlock`
* @param _cloneTokenName Name of the clone token
* @param _cloneDecimalUnits Number of decimals of the smallest unit
* @param _cloneTokenSymbol Symbol of the clone token
* @param _snapshotBlock Block when the distribution of the parent token is
* copied to set the initial distribution of the new clone token;
* if the block is zero than the actual block, the current block is used
* @param _transfersEnabled True if transfers are allowed in the clone
* @return The address of the new MiniMeToken Contract
*/
function createCloneToken(
string memory _cloneTokenName,
uint8 _cloneDecimalUnits,
string memory _cloneTokenSymbol,
uint _snapshotBlock,
bool _transfersEnabled
)
public
returns(address);
/**
* @notice Generates `_amount` tokens that are assigned to `_owner`
* @param _owner The address that will be assigned the new tokens
* @param _amount The quantity of tokens generated
* @return True if the tokens are generated correctly
*/
function generateTokens(
address _owner,
uint _amount
)
public
returns (bool);
/**
* @notice Burns `_amount` tokens from `_owner`
* @param _owner The address that will lose the tokens
* @param _amount The quantity of tokens to burn
* @return True if the tokens are burned correctly
*/
function destroyTokens(
address _owner,
uint _amount
)
public
returns (bool);
/**
* @notice Enables token holders to transfer their tokens freely if true
* @param _transfersEnabled True if transfers are allowed in the clone
*/
function enableTransfers(bool _transfersEnabled) public;
/**
* @notice This method can be used by the controller to extract mistakenly
* sent tokens to this contract.
* @param _token The address of the token contract that you want to recover
* set to 0 in case you want to extract ether.
*/
function claimTokens(address _token) public;
/**
* @dev Queries the balance of `_owner` at a specific `_blockNumber`
* @param _owner The address from which the balance will be retrieved
* @param _blockNumber The block number when the balance is queried
* @return The balance at `_blockNumber`
*/
function balanceOfAt(
address _owner,
uint _blockNumber
)
public
view
returns (uint);
/**
* @notice Total amount of tokens at a specific `_blockNumber`.
* @param _blockNumber The block number when the totalSupply is queried
* @return The total amount of tokens at `_blockNumber`
*/
function totalSupplyAt(uint _blockNumber) public view returns(uint);
}

View File

@ -0,0 +1,421 @@
pragma solidity ^0.5.1;
import './SafeMath.sol';
contract BancorFormula {
using SafeMath for uint256;
uint256 private constant ONE = 1;
uint32 private constant MAX_WEIGHT = 1000000;
uint8 private constant MIN_PRECISION = 32;
uint8 private constant MAX_PRECISION = 127;
/**
Auto-generated via 'PrintIntScalingFactors.py'
*/
uint256 private constant FIXED_1 = 0x080000000000000000000000000000000;
uint256 private constant FIXED_2 = 0x100000000000000000000000000000000;
uint256 private constant MAX_NUM = 0x200000000000000000000000000000000;
/**
Auto-generated via 'PrintLn2ScalingFactors.py'
*/
uint256 private constant LN2_NUMERATOR = 0x3f80fe03f80fe03f80fe03f80fe03f8;
uint256 private constant LN2_DENOMINATOR = 0x5b9de1d10bf4103d647b0955897ba80;
/**
Auto-generated via 'PrintFunctionOptimalLog.py' and 'PrintFunctionOptimalExp.py'
*/
uint256 private constant OPT_LOG_MAX_VAL = 0x15bf0a8b1457695355fb8ac404e7a79e3;
uint256 private constant OPT_EXP_MAX_VAL = 0x800000000000000000000000000000000;
/**
Auto-generated via 'PrintFunctionConstructor.py'
*/
uint256[128] private maxExpArray;
constructor() public {
// maxExpArray[ 0] = 0x6bffffffffffffffffffffffffffffffff;
// maxExpArray[ 1] = 0x67ffffffffffffffffffffffffffffffff;
// maxExpArray[ 2] = 0x637fffffffffffffffffffffffffffffff;
// maxExpArray[ 3] = 0x5f6fffffffffffffffffffffffffffffff;
// maxExpArray[ 4] = 0x5b77ffffffffffffffffffffffffffffff;
// maxExpArray[ 5] = 0x57b3ffffffffffffffffffffffffffffff;
// maxExpArray[ 6] = 0x5419ffffffffffffffffffffffffffffff;
// maxExpArray[ 7] = 0x50a2ffffffffffffffffffffffffffffff;
// maxExpArray[ 8] = 0x4d517fffffffffffffffffffffffffffff;
// maxExpArray[ 9] = 0x4a233fffffffffffffffffffffffffffff;
// maxExpArray[ 10] = 0x47165fffffffffffffffffffffffffffff;
// maxExpArray[ 11] = 0x4429afffffffffffffffffffffffffffff;
// maxExpArray[ 12] = 0x415bc7ffffffffffffffffffffffffffff;
// maxExpArray[ 13] = 0x3eab73ffffffffffffffffffffffffffff;
// maxExpArray[ 14] = 0x3c1771ffffffffffffffffffffffffffff;
// maxExpArray[ 15] = 0x399e96ffffffffffffffffffffffffffff;
// maxExpArray[ 16] = 0x373fc47fffffffffffffffffffffffffff;
// maxExpArray[ 17] = 0x34f9e8ffffffffffffffffffffffffffff;
// maxExpArray[ 18] = 0x32cbfd5fffffffffffffffffffffffffff;
// maxExpArray[ 19] = 0x30b5057fffffffffffffffffffffffffff;
// maxExpArray[ 20] = 0x2eb40f9fffffffffffffffffffffffffff;
// maxExpArray[ 21] = 0x2cc8340fffffffffffffffffffffffffff;
// maxExpArray[ 22] = 0x2af09481ffffffffffffffffffffffffff;
// maxExpArray[ 23] = 0x292c5bddffffffffffffffffffffffffff;
// maxExpArray[ 24] = 0x277abdcdffffffffffffffffffffffffff;
// maxExpArray[ 25] = 0x25daf6657fffffffffffffffffffffffff;
// maxExpArray[ 26] = 0x244c49c65fffffffffffffffffffffffff;
// maxExpArray[ 27] = 0x22ce03cd5fffffffffffffffffffffffff;
// maxExpArray[ 28] = 0x215f77c047ffffffffffffffffffffffff;
// maxExpArray[ 29] = 0x1fffffffffffffffffffffffffffffffff;
// maxExpArray[ 30] = 0x1eaefdbdabffffffffffffffffffffffff;
// maxExpArray[ 31] = 0x1d6bd8b2ebffffffffffffffffffffffff;
maxExpArray[ 32] = 0x1c35fedd14ffffffffffffffffffffffff;
maxExpArray[ 33] = 0x1b0ce43b323fffffffffffffffffffffff;
maxExpArray[ 34] = 0x19f0028ec1ffffffffffffffffffffffff;
maxExpArray[ 35] = 0x18ded91f0e7fffffffffffffffffffffff;
maxExpArray[ 36] = 0x17d8ec7f0417ffffffffffffffffffffff;
maxExpArray[ 37] = 0x16ddc6556cdbffffffffffffffffffffff;
maxExpArray[ 38] = 0x15ecf52776a1ffffffffffffffffffffff;
maxExpArray[ 39] = 0x15060c256cb2ffffffffffffffffffffff;
maxExpArray[ 40] = 0x1428a2f98d72ffffffffffffffffffffff;
maxExpArray[ 41] = 0x13545598e5c23fffffffffffffffffffff;
maxExpArray[ 42] = 0x1288c4161ce1dfffffffffffffffffffff;
maxExpArray[ 43] = 0x11c592761c666fffffffffffffffffffff;
maxExpArray[ 44] = 0x110a688680a757ffffffffffffffffffff;
maxExpArray[ 45] = 0x1056f1b5bedf77ffffffffffffffffffff;
maxExpArray[ 46] = 0x0faadceceeff8bffffffffffffffffffff;
maxExpArray[ 47] = 0x0f05dc6b27edadffffffffffffffffffff;
maxExpArray[ 48] = 0x0e67a5a25da4107fffffffffffffffffff;
maxExpArray[ 49] = 0x0dcff115b14eedffffffffffffffffffff;
maxExpArray[ 50] = 0x0d3e7a392431239fffffffffffffffffff;
maxExpArray[ 51] = 0x0cb2ff529eb71e4fffffffffffffffffff;
maxExpArray[ 52] = 0x0c2d415c3db974afffffffffffffffffff;
maxExpArray[ 53] = 0x0bad03e7d883f69bffffffffffffffffff;
maxExpArray[ 54] = 0x0b320d03b2c343d5ffffffffffffffffff;
maxExpArray[ 55] = 0x0abc25204e02828dffffffffffffffffff;
maxExpArray[ 56] = 0x0a4b16f74ee4bb207fffffffffffffffff;
maxExpArray[ 57] = 0x09deaf736ac1f569ffffffffffffffffff;
maxExpArray[ 58] = 0x0976bd9952c7aa957fffffffffffffffff;
maxExpArray[ 59] = 0x09131271922eaa606fffffffffffffffff;
maxExpArray[ 60] = 0x08b380f3558668c46fffffffffffffffff;
maxExpArray[ 61] = 0x0857ddf0117efa215bffffffffffffffff;
maxExpArray[ 62] = 0x07ffffffffffffffffffffffffffffffff;
maxExpArray[ 63] = 0x07abbf6f6abb9d087fffffffffffffffff;
maxExpArray[ 64] = 0x075af62cbac95f7dfa7fffffffffffffff;
maxExpArray[ 65] = 0x070d7fb7452e187ac13fffffffffffffff;
maxExpArray[ 66] = 0x06c3390ecc8af379295fffffffffffffff;
maxExpArray[ 67] = 0x067c00a3b07ffc01fd6fffffffffffffff;
maxExpArray[ 68] = 0x0637b647c39cbb9d3d27ffffffffffffff;
maxExpArray[ 69] = 0x05f63b1fc104dbd39587ffffffffffffff;
maxExpArray[ 70] = 0x05b771955b36e12f7235ffffffffffffff;
maxExpArray[ 71] = 0x057b3d49dda84556d6f6ffffffffffffff;
maxExpArray[ 72] = 0x054183095b2c8ececf30ffffffffffffff;
maxExpArray[ 73] = 0x050a28be635ca2b888f77fffffffffffff;
maxExpArray[ 74] = 0x04d5156639708c9db33c3fffffffffffff;
maxExpArray[ 75] = 0x04a23105873875bd52dfdfffffffffffff;
maxExpArray[ 76] = 0x0471649d87199aa990756fffffffffffff;
maxExpArray[ 77] = 0x04429a21a029d4c1457cfbffffffffffff;
maxExpArray[ 78] = 0x0415bc6d6fb7dd71af2cb3ffffffffffff;
maxExpArray[ 79] = 0x03eab73b3bbfe282243ce1ffffffffffff;
maxExpArray[ 80] = 0x03c1771ac9fb6b4c18e229ffffffffffff;
maxExpArray[ 81] = 0x0399e96897690418f785257fffffffffff;
maxExpArray[ 82] = 0x0373fc456c53bb779bf0ea9fffffffffff;
maxExpArray[ 83] = 0x034f9e8e490c48e67e6ab8bfffffffffff;
maxExpArray[ 84] = 0x032cbfd4a7adc790560b3337ffffffffff;
maxExpArray[ 85] = 0x030b50570f6e5d2acca94613ffffffffff;
maxExpArray[ 86] = 0x02eb40f9f620fda6b56c2861ffffffffff;
maxExpArray[ 87] = 0x02cc8340ecb0d0f520a6af58ffffffffff;
maxExpArray[ 88] = 0x02af09481380a0a35cf1ba02ffffffffff;
maxExpArray[ 89] = 0x0292c5bdd3b92ec810287b1b3fffffffff;
maxExpArray[ 90] = 0x0277abdcdab07d5a77ac6d6b9fffffffff;
maxExpArray[ 91] = 0x025daf6654b1eaa55fd64df5efffffffff;
maxExpArray[ 92] = 0x0244c49c648baa98192dce88b7ffffffff;
maxExpArray[ 93] = 0x022ce03cd5619a311b2471268bffffffff;
maxExpArray[ 94] = 0x0215f77c045fbe885654a44a0fffffffff;
maxExpArray[ 95] = 0x01ffffffffffffffffffffffffffffffff;
maxExpArray[ 96] = 0x01eaefdbdaaee7421fc4d3ede5ffffffff;
maxExpArray[ 97] = 0x01d6bd8b2eb257df7e8ca57b09bfffffff;
maxExpArray[ 98] = 0x01c35fedd14b861eb0443f7f133fffffff;
maxExpArray[ 99] = 0x01b0ce43b322bcde4a56e8ada5afffffff;
maxExpArray[100] = 0x019f0028ec1fff007f5a195a39dfffffff;
maxExpArray[101] = 0x018ded91f0e72ee74f49b15ba527ffffff;
maxExpArray[102] = 0x017d8ec7f04136f4e5615fd41a63ffffff;
maxExpArray[103] = 0x016ddc6556cdb84bdc8d12d22e6fffffff;
maxExpArray[104] = 0x015ecf52776a1155b5bd8395814f7fffff;
maxExpArray[105] = 0x015060c256cb23b3b3cc3754cf40ffffff;
maxExpArray[106] = 0x01428a2f98d728ae223ddab715be3fffff;
maxExpArray[107] = 0x013545598e5c23276ccf0ede68034fffff;
maxExpArray[108] = 0x01288c4161ce1d6f54b7f61081194fffff;
maxExpArray[109] = 0x011c592761c666aa641d5a01a40f17ffff;
maxExpArray[110] = 0x0110a688680a7530515f3e6e6cfdcdffff;
maxExpArray[111] = 0x01056f1b5bedf75c6bcb2ce8aed428ffff;
maxExpArray[112] = 0x00faadceceeff8a0890f3875f008277fff;
maxExpArray[113] = 0x00f05dc6b27edad306388a600f6ba0bfff;
maxExpArray[114] = 0x00e67a5a25da41063de1495d5b18cdbfff;
maxExpArray[115] = 0x00dcff115b14eedde6fc3aa5353f2e4fff;
maxExpArray[116] = 0x00d3e7a3924312399f9aae2e0f868f8fff;
maxExpArray[117] = 0x00cb2ff529eb71e41582cccd5a1ee26fff;
maxExpArray[118] = 0x00c2d415c3db974ab32a51840c0b67edff;
maxExpArray[119] = 0x00bad03e7d883f69ad5b0a186184e06bff;
maxExpArray[120] = 0x00b320d03b2c343d4829abd6075f0cc5ff;
maxExpArray[121] = 0x00abc25204e02828d73c6e80bcdb1a95bf;
maxExpArray[122] = 0x00a4b16f74ee4bb2040a1ec6c15fbbf2df;
maxExpArray[123] = 0x009deaf736ac1f569deb1b5ae3f36c130f;
maxExpArray[124] = 0x00976bd9952c7aa957f5937d790ef65037;
maxExpArray[125] = 0x009131271922eaa6064b73a22d0bd4f2bf;
maxExpArray[126] = 0x008b380f3558668c46c91c49a2f8e967b9;
maxExpArray[127] = 0x00857ddf0117efa215952912839f6473e6;
}
/**
General Description:
Determine a value of precision.
Calculate an integer approximation of (_baseN / _baseD) ^ (_expN / _expD) * 2 ^ precision.
Return the result along with the precision used.
Detailed Description:
Instead of calculating "base ^ exp", we calculate "e ^ (log(base) * exp)".
The value of "log(base)" is represented with an integer slightly smaller than "log(base) * 2 ^ precision".
The larger "precision" is, the more accurately this value represents the real value.
However, the larger "precision" is, the more bits are required in order to store this value.
And the exponentiation function, which takes "x" and calculates "e ^ x", is limited to a maximum exponent (maximum value of "x").
This maximum exponent depends on the "precision" used, and it is given by "maxExpArray[precision] >> (MAX_PRECISION - precision)".
Hence we need to determine the highest precision which can be used for the given input, before calling the exponentiation function.
This allows us to compute "base ^ exp" with maximum accuracy and without exceeding 256 bits in any of the intermediate computations.
This functions assumes that "_expN < 2 ^ 256 / log(MAX_NUM - 1)", otherwise the multiplication should be replaced with a "safeMul".
*/
function power(uint256 _baseN, uint256 _baseD, uint32 _expN, uint32 _expD) internal view returns (uint256, uint8) {
require(_baseN < MAX_NUM);
uint256 baseLog;
uint256 base = _baseN * FIXED_1 / _baseD;
if (base < OPT_LOG_MAX_VAL) {
baseLog = optimalLog(base);
}
else {
baseLog = generalLog(base);
}
uint256 baseLogTimesExp = baseLog * _expN / _expD;
if (baseLogTimesExp < OPT_EXP_MAX_VAL) {
return (optimalExp(baseLogTimesExp), MAX_PRECISION);
}
else {
uint8 precision = findPositionInMaxExpArray(baseLogTimesExp);
return (generalExp(baseLogTimesExp >> (MAX_PRECISION - precision), precision), precision);
}
}
/**
Compute log(x / FIXED_1) * FIXED_1.
This functions assumes that "x >= FIXED_1", because the output would be negative otherwise.
*/
function generalLog(uint256 x) internal pure returns (uint256) {
uint256 res = 0;
// If x >= 2, then we compute the integer part of log2(x), which is larger than 0.
if (x >= FIXED_2) {
uint8 count = floorLog2(x / FIXED_1);
x >>= count; // now x < 2
res = count * FIXED_1;
}
// If x > 1, then we compute the fraction part of log2(x), which is larger than 0.
if (x > FIXED_1) {
for (uint8 i = MAX_PRECISION; i > 0; --i) {
x = (x * x) / FIXED_1; // now 1 < x < 4
if (x >= FIXED_2) {
x >>= 1; // now 1 < x < 2
res += ONE << (i - 1);
}
}
}
return res * LN2_NUMERATOR / LN2_DENOMINATOR;
}
/**
Compute the largest integer smaller than or equal to the binary logarithm of the input.
*/
function floorLog2(uint256 _n) internal pure returns (uint8) {
uint8 res = 0;
if (_n < 256) {
// At most 8 iterations
while (_n > 1) {
_n >>= 1;
res += 1;
}
}
else {
// Exactly 8 iterations
for (uint8 s = 128; s > 0; s >>= 1) {
if (_n >= (ONE << s)) {
_n >>= s;
res |= s;
}
}
}
return res;
}
/**
The global "maxExpArray" is sorted in descending order, and therefore the following statements are equivalent:
- This function finds the position of [the smallest value in "maxExpArray" larger than or equal to "x"]
- This function finds the highest position of [a value in "maxExpArray" larger than or equal to "x"]
*/
function findPositionInMaxExpArray(uint256 _x) internal view returns (uint8) {
uint8 lo = MIN_PRECISION;
uint8 hi = MAX_PRECISION;
while (lo + 1 < hi) {
uint8 mid = (lo + hi) / 2;
if (maxExpArray[mid] >= _x)
lo = mid;
else
hi = mid;
}
if (maxExpArray[hi] >= _x)
return hi;
if (maxExpArray[lo] >= _x)
return lo;
require(false);
return 0;
}
/**
This function can be auto-generated by the script 'PrintFunctionGeneralExp.py'.
It approximates "e ^ x" via maclaurin summation: "(x^0)/0! + (x^1)/1! + ... + (x^n)/n!".
It returns "e ^ (x / 2 ^ precision) * 2 ^ precision", that is, the result is upshifted for accuracy.
The global "maxExpArray" maps each "precision" to "((maximumExponent + 1) << (MAX_PRECISION - precision)) - 1".
The maximum permitted value for "x" is therefore given by "maxExpArray[precision] >> (MAX_PRECISION - precision)".
*/
function generalExp(uint256 _x, uint8 _precision) internal pure returns (uint256) {
uint256 xi = _x;
uint256 res = 0;
xi = (xi * _x) >> _precision; res += xi * 0x3442c4e6074a82f1797f72ac0000000; // add x^02 * (33! / 02!)
xi = (xi * _x) >> _precision; res += xi * 0x116b96f757c380fb287fd0e40000000; // add x^03 * (33! / 03!)
xi = (xi * _x) >> _precision; res += xi * 0x045ae5bdd5f0e03eca1ff4390000000; // add x^04 * (33! / 04!)
xi = (xi * _x) >> _precision; res += xi * 0x00defabf91302cd95b9ffda50000000; // add x^05 * (33! / 05!)
xi = (xi * _x) >> _precision; res += xi * 0x002529ca9832b22439efff9b8000000; // add x^06 * (33! / 06!)
xi = (xi * _x) >> _precision; res += xi * 0x00054f1cf12bd04e516b6da88000000; // add x^07 * (33! / 07!)
xi = (xi * _x) >> _precision; res += xi * 0x0000a9e39e257a09ca2d6db51000000; // add x^08 * (33! / 08!)
xi = (xi * _x) >> _precision; res += xi * 0x000012e066e7b839fa050c309000000; // add x^09 * (33! / 09!)
xi = (xi * _x) >> _precision; res += xi * 0x000001e33d7d926c329a1ad1a800000; // add x^10 * (33! / 10!)
xi = (xi * _x) >> _precision; res += xi * 0x0000002bee513bdb4a6b19b5f800000; // add x^11 * (33! / 11!)
xi = (xi * _x) >> _precision; res += xi * 0x00000003a9316fa79b88eccf2a00000; // add x^12 * (33! / 12!)
xi = (xi * _x) >> _precision; res += xi * 0x0000000048177ebe1fa812375200000; // add x^13 * (33! / 13!)
xi = (xi * _x) >> _precision; res += xi * 0x0000000005263fe90242dcbacf00000; // add x^14 * (33! / 14!)
xi = (xi * _x) >> _precision; res += xi * 0x000000000057e22099c030d94100000; // add x^15 * (33! / 15!)
xi = (xi * _x) >> _precision; res += xi * 0x0000000000057e22099c030d9410000; // add x^16 * (33! / 16!)
xi = (xi * _x) >> _precision; res += xi * 0x00000000000052b6b54569976310000; // add x^17 * (33! / 17!)
xi = (xi * _x) >> _precision; res += xi * 0x00000000000004985f67696bf748000; // add x^18 * (33! / 18!)
xi = (xi * _x) >> _precision; res += xi * 0x000000000000003dea12ea99e498000; // add x^19 * (33! / 19!)
xi = (xi * _x) >> _precision; res += xi * 0x00000000000000031880f2214b6e000; // add x^20 * (33! / 20!)
xi = (xi * _x) >> _precision; res += xi * 0x000000000000000025bcff56eb36000; // add x^21 * (33! / 21!)
xi = (xi * _x) >> _precision; res += xi * 0x000000000000000001b722e10ab1000; // add x^22 * (33! / 22!)
xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000001317c70077000; // add x^23 * (33! / 23!)
xi = (xi * _x) >> _precision; res += xi * 0x00000000000000000000cba84aafa00; // add x^24 * (33! / 24!)
xi = (xi * _x) >> _precision; res += xi * 0x00000000000000000000082573a0a00; // add x^25 * (33! / 25!)
xi = (xi * _x) >> _precision; res += xi * 0x00000000000000000000005035ad900; // add x^26 * (33! / 26!)
xi = (xi * _x) >> _precision; res += xi * 0x000000000000000000000002f881b00; // add x^27 * (33! / 27!)
xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000001b29340; // add x^28 * (33! / 28!)
xi = (xi * _x) >> _precision; res += xi * 0x00000000000000000000000000efc40; // add x^29 * (33! / 29!)
xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000000007fe0; // add x^30 * (33! / 30!)
xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000000000420; // add x^31 * (33! / 31!)
xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000000000021; // add x^32 * (33! / 32!)
xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000000000001; // add x^33 * (33! / 33!)
return res / 0x688589cc0e9505e2f2fee5580000000 + _x + (ONE << _precision); // divide by 33! and then add x^1 / 1! + x^0 / 0!
}
/**
Return log(x / FIXED_1) * FIXED_1
Input range: FIXED_1 <= x <= LOG_EXP_MAX_VAL - 1
Auto-generated via 'PrintFunctionOptimalLog.py'
Detailed description:
- Rewrite the input as a product of natural exponents and a single residual r, such that 1 < r < 2
- The natural logarithm of each (pre-calculated) exponent is the degree of the exponent
- The natural logarithm of r is calculated via Taylor series for log(1 + x), where x = r - 1
- The natural logarithm of the input is calculated by summing up the intermediate results above
- For example: log(250) = log(e^4 * e^1 * e^0.5 * 1.021692859) = 4 + 1 + 0.5 + log(1 + 0.021692859)
*/
function optimalLog(uint256 x) internal pure returns (uint256) {
uint256 res = 0;
uint256 y;
uint256 z;
uint256 w;
if (x >= 0xd3094c70f034de4b96ff7d5b6f99fcd8) {res += 0x40000000000000000000000000000000; x = x * FIXED_1 / 0xd3094c70f034de4b96ff7d5b6f99fcd8;} // add 1 / 2^1
if (x >= 0xa45af1e1f40c333b3de1db4dd55f29a7) {res += 0x20000000000000000000000000000000; x = x * FIXED_1 / 0xa45af1e1f40c333b3de1db4dd55f29a7;} // add 1 / 2^2
if (x >= 0x910b022db7ae67ce76b441c27035c6a1) {res += 0x10000000000000000000000000000000; x = x * FIXED_1 / 0x910b022db7ae67ce76b441c27035c6a1;} // add 1 / 2^3
if (x >= 0x88415abbe9a76bead8d00cf112e4d4a8) {res += 0x08000000000000000000000000000000; x = x * FIXED_1 / 0x88415abbe9a76bead8d00cf112e4d4a8;} // add 1 / 2^4
if (x >= 0x84102b00893f64c705e841d5d4064bd3) {res += 0x04000000000000000000000000000000; x = x * FIXED_1 / 0x84102b00893f64c705e841d5d4064bd3;} // add 1 / 2^5
if (x >= 0x8204055aaef1c8bd5c3259f4822735a2) {res += 0x02000000000000000000000000000000; x = x * FIXED_1 / 0x8204055aaef1c8bd5c3259f4822735a2;} // add 1 / 2^6
if (x >= 0x810100ab00222d861931c15e39b44e99) {res += 0x01000000000000000000000000000000; x = x * FIXED_1 / 0x810100ab00222d861931c15e39b44e99;} // add 1 / 2^7
if (x >= 0x808040155aabbbe9451521693554f733) {res += 0x00800000000000000000000000000000; x = x * FIXED_1 / 0x808040155aabbbe9451521693554f733;} // add 1 / 2^8
z = y = x - FIXED_1;
w = y * y / FIXED_1;
res += z * (0x100000000000000000000000000000000 - y) / 0x100000000000000000000000000000000; z = z * w / FIXED_1; // add y^01 / 01 - y^02 / 02
res += z * (0x0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - y) / 0x200000000000000000000000000000000; z = z * w / FIXED_1; // add y^03 / 03 - y^04 / 04
res += z * (0x099999999999999999999999999999999 - y) / 0x300000000000000000000000000000000; z = z * w / FIXED_1; // add y^05 / 05 - y^06 / 06
res += z * (0x092492492492492492492492492492492 - y) / 0x400000000000000000000000000000000; z = z * w / FIXED_1; // add y^07 / 07 - y^08 / 08
res += z * (0x08e38e38e38e38e38e38e38e38e38e38e - y) / 0x500000000000000000000000000000000; z = z * w / FIXED_1; // add y^09 / 09 - y^10 / 10
res += z * (0x08ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8b - y) / 0x600000000000000000000000000000000; z = z * w / FIXED_1; // add y^11 / 11 - y^12 / 12
res += z * (0x089d89d89d89d89d89d89d89d89d89d89 - y) / 0x700000000000000000000000000000000; z = z * w / FIXED_1; // add y^13 / 13 - y^14 / 14
res += z * (0x088888888888888888888888888888888 - y) / 0x800000000000000000000000000000000; // add y^15 / 15 - y^16 / 16
return res;
}
/**
Return e ^ (x / FIXED_1) * FIXED_1
Input range: 0 <= x <= OPT_EXP_MAX_VAL - 1
Auto-generated via 'PrintFunctionOptimalExp.py'
Detailed description:
- Rewrite the input as a sum of binary exponents and a single residual r, as small as possible
- The exponentiation of each binary exponent is given (pre-calculated)
- The exponentiation of r is calculated via Taylor series for e^x, where x = r
- The exponentiation of the input is calculated by multiplying the intermediate results above
- For example: e^5.521692859 = e^(4 + 1 + 0.5 + 0.021692859) = e^4 * e^1 * e^0.5 * e^0.021692859
*/
function optimalExp(uint256 x) internal pure returns (uint256) {
uint256 res = 0;
uint256 y;
uint256 z;
z = y = x % 0x10000000000000000000000000000000; // get the input modulo 2^(-3)
z = z * y / FIXED_1; res += z * 0x10e1b3be415a0000; // add y^02 * (20! / 02!)
z = z * y / FIXED_1; res += z * 0x05a0913f6b1e0000; // add y^03 * (20! / 03!)
z = z * y / FIXED_1; res += z * 0x0168244fdac78000; // add y^04 * (20! / 04!)
z = z * y / FIXED_1; res += z * 0x004807432bc18000; // add y^05 * (20! / 05!)
z = z * y / FIXED_1; res += z * 0x000c0135dca04000; // add y^06 * (20! / 06!)
z = z * y / FIXED_1; res += z * 0x0001b707b1cdc000; // add y^07 * (20! / 07!)
z = z * y / FIXED_1; res += z * 0x000036e0f639b800; // add y^08 * (20! / 08!)
z = z * y / FIXED_1; res += z * 0x00000618fee9f800; // add y^09 * (20! / 09!)
z = z * y / FIXED_1; res += z * 0x0000009c197dcc00; // add y^10 * (20! / 10!)
z = z * y / FIXED_1; res += z * 0x0000000e30dce400; // add y^11 * (20! / 11!)
z = z * y / FIXED_1; res += z * 0x000000012ebd1300; // add y^12 * (20! / 12!)
z = z * y / FIXED_1; res += z * 0x0000000017499f00; // add y^13 * (20! / 13!)
z = z * y / FIXED_1; res += z * 0x0000000001a9d480; // add y^14 * (20! / 14!)
z = z * y / FIXED_1; res += z * 0x00000000001c6380; // add y^15 * (20! / 15!)
z = z * y / FIXED_1; res += z * 0x000000000001c638; // add y^16 * (20! / 16!)
z = z * y / FIXED_1; res += z * 0x0000000000001ab8; // add y^17 * (20! / 17!)
z = z * y / FIXED_1; res += z * 0x000000000000017c; // add y^18 * (20! / 18!)
z = z * y / FIXED_1; res += z * 0x0000000000000014; // add y^19 * (20! / 19!)
z = z * y / FIXED_1; res += z * 0x0000000000000001; // add y^20 * (20! / 20!)
res = res / 0x21c3677c82b40000 + y + FIXED_1; // divide by 20! and then add y^1 / 1! + y^0 / 0!
if ((x & 0x010000000000000000000000000000000) != 0) res = res * 0x1c3d6a24ed82218787d624d3e5eba95f9 / 0x18ebef9eac820ae8682b9793ac6d1e776; // multiply by e^2^(-3)
if ((x & 0x020000000000000000000000000000000) != 0) res = res * 0x18ebef9eac820ae8682b9793ac6d1e778 / 0x1368b2fc6f9609fe7aceb46aa619baed4; // multiply by e^2^(-2)
if ((x & 0x040000000000000000000000000000000) != 0) res = res * 0x1368b2fc6f9609fe7aceb46aa619baed5 / 0x0bc5ab1b16779be3575bd8f0520a9f21f; // multiply by e^2^(-1)
if ((x & 0x080000000000000000000000000000000) != 0) res = res * 0x0bc5ab1b16779be3575bd8f0520a9f21e / 0x0454aaa8efe072e7f6ddbab84b40a55c9; // multiply by e^2^(+0)
if ((x & 0x100000000000000000000000000000000) != 0) res = res * 0x0454aaa8efe072e7f6ddbab84b40a55c5 / 0x00960aadc109e7a3bf4578099615711ea; // multiply by e^2^(+1)
if ((x & 0x200000000000000000000000000000000) != 0) res = res * 0x00960aadc109e7a3bf4578099615711d7 / 0x0002bf84208204f5977f9a8cf01fdce3d; // multiply by e^2^(+2)
if ((x & 0x400000000000000000000000000000000) != 0) res = res * 0x0002bf84208204f5977f9a8cf01fdc307 / 0x0000003c6ab775dd0b95b4cbee7e65d11; // multiply by e^2^(+3)
return res;
}
}

View File

@ -0,0 +1,58 @@
pragma solidity ^0.5.1;
/*
Library for basic math operations with overflow/underflow protection
*/
library SafeMath {
/**
@dev returns the sum of _x and _y, reverts if the calculation overflows
@param _x value 1
@param _y value 2
@return sum
*/
function add(uint256 _x, uint256 _y) internal pure returns (uint256) {
uint256 z = _x + _y;
require(z >= _x);
return z;
}
/**
@dev returns the difference of _x minus _y, reverts if the calculation underflows
@param _x minuend
@param _y subtrahend
@return difference
*/
function sub(uint256 _x, uint256 _y) internal pure returns (uint256) {
require(_x >= _y);
return _x - _y;
}
/**
@dev returns the product of multiplying _x by _y, reverts if the calculation overflows
@param _x factor 1
@param _y factor 2
@return product
*/
function mul(uint256 _x, uint256 _y) internal pure returns (uint256) {
// gas optimization
if (_x == 0)
return 0;
uint256 z = _x * _y;
require(z / _x == _y);
return z;
}
/**
@dev Integer division of two numbers truncating the quotient, reverts on division by zero.
@param _x dividend
@param _y divisor
@return quotient
*/
function div(uint256 _x, uint256 _y) internal pure returns (uint256) {
require(_y > 0);
uint256 c = _x / _y;
return c;
}
}

20
embark.json Normal file
View File

@ -0,0 +1,20 @@
{
"contracts": ["contracts/**"],
"buildDir": "build/",
"config": "config/",
"versions": {
"web3": "1.0.0-beta",
"solc": "0.5.1",
"ipfs-api": "17.2.4"
},
"plugins": {
"embarkjs-connector-web3": {}
},
"options": {
"solc": {
"optimize": true,
"optimize-runs": 200
}
},
"generationDir": "embarkArtifacts"
}

5340
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
{
"name": "discover-dapps",
"version": "0.1.0",
"homepage": "https://status-im.github.io/discover-dapps",
"version": "0.2.0",
"private": true,
"dependencies": {
"connected-react-router": "^6.3.2",
@ -25,7 +26,8 @@
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"staging-deploy": "npm run build && aws s3 sync --acl public-read build s3://status-discover-dapps-staging/ --delete && rm -rf build"
"predeploy": "npm run build",
"deploy": "gh-pages -d build"
},
"husky": {
"hooks": {
@ -48,9 +50,11 @@
"not op_mini all"
],
"devDependencies": {
"embarkjs-connector-web3": "^4.0.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-config-prettier": "^4.1.0",
"eslint-plugin-prettier": "^3.0.1",
"gh-pages": "^2.0.1",
"husky": "^1.3.1",
"lint-staged": "^8.1.5",
"prettier": "^1.16.4"

43
test/contract_spec.js Normal file
View File

@ -0,0 +1,43 @@
// /*global contract, config, it, assert*/
/*
const SimpleStorage = require('Embark/contracts/SimpleStorage');
let accounts;
// For documentation please see https://embark.status.im/docs/contracts_testing.html
config({
//deployment: {
// accounts: [
// // you can configure custom accounts with a custom balance
// // see https://embark.status.im/docs/contracts_testing.html#Configuring-accounts
// ]
//},
contracts: {
"SimpleStorage": {
args: [100]
}
}
}, (_err, web3_accounts) => {
accounts = web3_accounts
});
contract("SimpleStorage", function () {
this.timeout(0);
it("should set constructor value", async function () {
let result = await SimpleStorage.methods.storedData().call();
assert.strictEqual(parseInt(result, 10), 100);
});
it("set storage value", async function () {
await SimpleStorage.methods.set(150).send();
let result = await SimpleStorage.methods.get().call();
assert.strictEqual(parseInt(result, 10), 150);
});
it("should have account with balance", async function() {
let balance = await web3.eth.getBalance(accounts[0]);
assert.ok(parseInt(balance, 10) > 0);
});
}
*/