ERC20
This contract is an ERC20 token.
Name
Neumark
Symbol
NEU
Decimals
18
Total Supply
69,959,167 NEU
About
link
description
Neumark (NEU) is a cryptocurrency and operates on the Ethereum platform. Neumark has a current supply of 65,408,131.77641533 with 0 in circulation. The last known price of Neumark is 0.12421957 USD and is up 4.01 over the last 24 hours. It is currently trading on 6 active market(s) with $10.03 traded over the last 24 hours. More information can be found at http://neufund.org/.
Stats
Public Functions
44
Event Types
8
Code Size
74,189 bytes
Events (8) keyboard_arrow_up
Constants (22) keyboard_arrow_up
ROLE_ACCESS_CONTROLLER Constant
bytes32 help
0xac42f8beb17975ed062dcb80c63e6d203ef1c2c335ced149dc5664cc671cb7da
ROLE_LOCKED_ACCOUNT_ADMIN Constant
bytes32 help
0x4675da546d2d92c5b86c4f726a9e61010dce91cccc2491ce6019e78b09d2572e
ROLE_WHITELIST_ADMIN Constant
bytes32 help
0xaef456e7c864418e1d2a40d996ca4febf3a7e317fe3af5a7ea4dda59033bbe5c
ROLE_NEUMARK_ISSUER Constant
bytes32 help
0x921c3afa1f1fff707a785f953a1e197bd28c9c50e300424e015953cbf120c06c
ROLE_NEUMARK_BURNER Constant
bytes32 help
0x19ce331285f41739cd3362a3ec176edffe014311c0f8075834fdd19d6718e69f
ROLE_SNAPSHOT_CREATOR Constant
bytes32 help
0x08c1785afc57f933523bc52583a72ce9e19b2241354e04dd86f41f887e3d8174
ROLE_TRANSFER_ADMIN Constant
bytes32 help
0xb6527e944caca3d151b1f94e49ac5e223142694860743e66164720e034ec9b19
ROLE_RECLAIMER Constant
bytes32 help
0x0542bbd0c672578966dcc525b30aa16723bb042675554ac5b0362f86b6e97dc5
ROLE_PLATFORM_OPERATOR_REPRESENTATIVE Constant
bytes32 help
0xb2b321377653f655206f71514ff9f150d0822d062a5abcf220d549e1da7999f0
ROLE_EURT_DEPOSIT_MANAGER Constant
bytes32 help
0x7c8ecdcba80ce87848d16ad77ef57cc196c208fc95c5638e4a48c681a34d4fe7
State Variables (17) keyboard_arrow_up
Functions
setAccessPolicy keyboard_arrow_up
Modifiers help
only checks for the following:
Source Code
function setAccessPolicy(IAccessPolicy newPolicy, address newAccessController)
public
only(ROLE_ACCESS_CONTROLLER)
{
// ROLE_ACCESS_CONTROLLER must be present
// under the new policy. This provides some
// protection against locking yourself out.
require(
newPolicy.allowed(
newAccessController,
ROLE_ACCESS_CONTROLLER,
this,
msg.sig
)
);
// We can now safely set the new policy without foot shooting.
IAccessPolicy oldPolicy = _accessPolicy;
_accessPolicy = newPolicy;
// Log event
LogAccessPolicyChanged(msg.sender, oldPolicy, newPolicy);
}
accessPolicy keyboard_arrow_up
reclaim keyboard_arrow_up
Modifiers help
only checks for the following:
Source Code
function reclaim(IBasicToken token) public only(ROLE_RECLAIMER) {
address reclaimer = msg.sender;
if (token == RECLAIM_ETHER) {
reclaimer.transfer(this.balance);
} else {
uint256 balance = token.balanceOf(this);
require(token.transfer(reclaimer, balance));
}
}
incremental keyboard_arrow_up
Requirements help
Source Code
function incremental(uint256 totalEuroUlps, uint256 euroUlps)
public
constant
returns (uint256 neumarkUlps)
{
require(totalEuroUlps + euroUlps >= totalEuroUlps);
uint256 from = cumulative(totalEuroUlps);
uint256 to = cumulative(totalEuroUlps + euroUlps);
// as expansion is not monotonic for large totalEuroUlps, assert below may fail
// example: totalEuroUlps=1.999999999999999999999000000e+27 and euroUlps=50
assert(to >= from);
return to - from;
}
incrementalInverse keyboard_arrow_up
Requirements help
Source Code
function incrementalInverse(uint256 totalEuroUlps, uint256 burnNeumarkUlps)
public
constant
returns (uint256 euroUlps)
{
uint256 totalNeumarkUlps = cumulative(totalEuroUlps);
require(totalNeumarkUlps >= burnNeumarkUlps);
uint256 fromNmk = totalNeumarkUlps - burnNeumarkUlps;
uint256 newTotalEuroUlps = cumulativeInverse(fromNmk, 0, totalEuroUlps);
// yes, this may overflow due to non monotonic inverse function
assert(totalEuroUlps >= newTotalEuroUlps);
return totalEuroUlps - newTotalEuroUlps;
}
incrementalInverse keyboard_arrow_up
Parameters help
Requirements help
Source Code
function incrementalInverse(
uint256 totalEuroUlps,
uint256 burnNeumarkUlps,
uint256 minEurUlps,
uint256 maxEurUlps
) public constant returns (uint256 euroUlps) {
uint256 totalNeumarkUlps = cumulative(totalEuroUlps);
require(totalNeumarkUlps >= burnNeumarkUlps);
uint256 fromNmk = totalNeumarkUlps - burnNeumarkUlps;
uint256 newTotalEuroUlps = cumulativeInverse(fromNmk, minEurUlps, maxEurUlps);
// yes, this may overflow due to non monotonic inverse function
assert(totalEuroUlps >= newTotalEuroUlps);
return totalEuroUlps - newTotalEuroUlps;
}
cumulative keyboard_arrow_up
Source Code
function cumulative(uint256 euroUlps)
public
constant
returns (uint256 neumarkUlps)
{
// Return the cap if euroUlps is above the limit.
if (euroUlps >= ISSUANCE_LIMIT_EUR_ULPS) {
return NEUMARK_CAP;
}
// use linear approximation above limit below
// binomial expansion does not guarantee monotonicity on uint256 precision for large euroUlps
if (euroUlps >= LINEAR_APPROX_LIMIT_EUR_ULPS) {
// (euroUlps - LINEAR_APPROX_LIMIT_EUR_ULPS) is small so expression does not overflow
return
NEUMARKS_AT_LINEAR_LIMIT_ULPS +
(TOT_LINEAR_NEUMARKS_ULPS * (euroUlps - LINEAR_APPROX_LIMIT_EUR_ULPS)) /
TOT_LINEAR_EUR_ULPS;
}
// Approximate cap-cap·(1-1/D)^n using the Binomial expansion
// http://galileo.phys.virginia.edu/classes/152.mf1i.spring02/Exponential_Function.htm
// Function[imax, -CAP*Sum[(-IR*EUR/CAP)^i/Factorial[i], {i, imax}]]
// which may be simplified to
// Function[imax, -CAP*Sum[(EUR)^i/(Factorial[i]*(-d)^i), {i, 1, imax}]]
// where d = cap/initial_reward
uint256 d = 230769230769230769230769231; // NEUMARK_CAP / INITIAL_REWARD_FRACTION
uint256 term = NEUMARK_CAP;
uint256 sum = 0;
uint256 denom = d;
do
assembly {
// We use assembler primarily to avoid the expensive
// divide-by-zero check solc inserts for the / operator.
term := div(mul(term, euroUlps), denom)
sum := add(sum, term)
denom := add(denom, d)
// sub next term as we have power of negative value in the binomial expansion
term := div(mul(term, euroUlps), denom)
sum := sub(sum, term)
denom := add(denom, d)
}
while (term != 0);
return sum;
}
cumulativeInverse keyboard_arrow_up
Requirements help
Source Code
function cumulativeInverse(
uint256 neumarkUlps,
uint256 minEurUlps,
uint256 maxEurUlps
) public constant returns (uint256 euroUlps) {
require(maxEurUlps >= minEurUlps);
require(cumulative(minEurUlps) <= neumarkUlps);
require(cumulative(maxEurUlps) >= neumarkUlps);
uint256 min = minEurUlps;
uint256 max = maxEurUlps;
// Binary search
while (max > min) {
uint256 mid = (max + min) / 2;
uint256 val = cumulative(mid);
// exact solution should not be used, a late points of the curve when many euroUlps are needed to
// increase by one nmkUlp this will lead to "indeterministic" inverse values that depend on the initial min and max
// and further binary division -> you can land at any of the euro value that is mapped to the same nmk value
// with condition below removed, binary search will point to the lowest eur value possible which is good because it cannot be exploited even with 0 gas costs
/* if (val == neumarkUlps) {
return mid;
}*/
// NOTE: approximate search (no inverse) must return upper element of the final range
// last step of approximate search is always (min, min+1) so new mid is (2*min+1)/2 => min
// so new min = mid + 1 = max which was upper range. and that ends the search
// NOTE: when there are multiple inverses for the same neumarkUlps, the `max` will be dragged down
// by `max = mid` expression to the lowest eur value of inverse. works only for ranges that cover all points of multiple inverse
if (val < neumarkUlps) {
min = mid + 1;
} else {
max = mid;
}
}
// NOTE: It is possible that there is no inverse
// for example curve(0) = 0 and curve(1) = 6, so
// there is no value y such that curve(y) = 5.
// When there is no inverse, we must return upper element of last search range.
// This has the effect of reversing the curve less when
// burning Neumarks. This ensures that Neumarks can always
// be burned. It also ensure that the total supply of Neumarks
// remains below the cap.
return max;
}
neumarkCap keyboard_arrow_up
initialRewardFraction keyboard_arrow_up
symbol keyboard_arrow_up
name keyboard_arrow_up
decimals keyboard_arrow_up
version keyboard_arrow_up
totalSupply keyboard_arrow_up
balanceOf keyboard_arrow_up
transfer keyboard_arrow_up
Requirements help
One or more of the following:
-
the result of calling parentSnapshotId
must be less than
UNKNOWN VALUE
- OR
the result of calling parentToken
must be equal to
UNKNOWN VALUE
null
Source Code
function transfer(address to, uint256 amount) public returns (bool success) {
mTransfer(msg.sender, to, amount);
return true;
}
transfer keyboard_arrow_up
Source Code
function transfer(
address to,
uint256 amount,
bytes data
) public returns (bool) {
// it is necessary to point out implementation to be called
BasicSnapshotToken.mTransfer(msg.sender, to, amount);
// Notify the receiving contract.
if (isContract(to)) {
IERC223Callback(to).onTokenTransfer(msg.sender, amount, data);
}
return true;
}
allowance keyboard_arrow_up
approve keyboard_arrow_up
Requirements help
null
One or more of the following:
Source Code
function approve(address spender, uint256 amount)
public
returns (bool success)
{
// Alerts the token controller of the approve function call
require(mOnApprove(msg.sender, spender, amount));
// To change the approve amount you first have to reduce the addresses`
// allowance to zero by calling `approve(_spender,0)` if it is not
// already 0 to mitigate the race condition described here:
// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
require((amount == 0) || (_allowed[msg.sender][spender] == 0));
_allowed[msg.sender][spender] = amount;
Approval(msg.sender, spender, amount);
return true;
}
transferFrom keyboard_arrow_up
Requirements help
amountApproved must be true
Source Code
function transferFrom(
address from,
address to,
uint256 amount
) public returns (bool success) {
// The standard ERC 20 transferFrom functionality
bool amountApproved = _allowed[from][msg.sender] >= amount;
require(amountApproved);
_allowed[from][msg.sender] -= amount;
mTransfer(from, to, amount);
return true;
}
approveAndCall keyboard_arrow_up
Source Code
function approveAndCall(
address spender,
uint256 amount,
bytes extraData
) public returns (bool success) {
require(approve(spender, amount));
success = IERC677Callback(spender).receiveApproval(
msg.sender,
amount,
this,
extraData
);
require(success);
return true;
}
totalSupplyAt keyboard_arrow_up
balanceOfAt keyboard_arrow_up
currentSnapshotId keyboard_arrow_up
parentToken keyboard_arrow_up
parentSnapshotId keyboard_arrow_up
allBalancesOf keyboard_arrow_up
Source Code
function allBalancesOf(address owner) external constant returns (uint256[2][]) {
/* very nice and working implementation below,
// copy to memory
Values[] memory values = _balances[owner];
do assembly {
// in memory structs have simple layout where every item occupies uint256
balances := values
} while (false);*/
Values[] storage values = _balances[owner];
uint256[2][] memory balances = new uint256[2][](values.length);
for (uint256 ii = 0; ii < values.length; ++ii) {
balances[ii] = [values[ii].snapshotId, values[ii].value];
}
return balances;
}
totalSupplyAtInternal keyboard_arrow_up
Source Code
function totalSupplyAtInternal(uint256 snapshotId)
public
constant
returns (uint256)
{
Values[] storage values = _totalSupplyValues;
// If there is a value, return it, reverts if value is in the future
if (hasValueAt(values, snapshotId)) {
return getValueAt(values, snapshotId, 0);
}
// Try parent contract at or before the fork
if (address(PARENT_TOKEN) != 0) {
uint256 earlierSnapshotId = PARENT_SNAPSHOT_ID > snapshotId
? snapshotId
: PARENT_SNAPSHOT_ID;
return PARENT_TOKEN.totalSupplyAt(earlierSnapshotId);
}
// Default to an empty balance
return 0;
}
createSnapshot keyboard_arrow_up
snapshotAt keyboard_arrow_up
Requirements help
Source Code
function snapshotAt(uint256 timestamp) public constant returns (uint256) {
require(timestamp < MAX_TIMESTAMP);
uint256 dayBase = 2**128 * (timestamp / 1 days);
return dayBase;
}
amendAgreement keyboard_arrow_up
Modifiers help
only checks for the following:
Source Code
function amendAgreement(string agreementUri)
public
only(ROLE_PLATFORM_OPERATOR_REPRESENTATIVE)
{
SignedAgreement memory amendment = SignedAgreement({
platformOperatorRepresentative: msg.sender,
signedBlockTimestamp: block.timestamp,
agreementUri: agreementUri
});
_amendments.push(amendment);
LogAgreementAmended(msg.sender, agreementUri);
}
ethereumForkArbiter keyboard_arrow_up
currentAgreement keyboard_arrow_up
Parameters help
This function has no parameters.
Requirements help
Source Code
function currentAgreement()
public
constant
returns (
address platformOperatorRepresentative,
uint256 signedBlockTimestamp,
string agreementUri,
uint256 index
)
{
require(_amendments.length > 0);
uint256 last = _amendments.length - 1;
SignedAgreement storage amendment = _amendments[last];
return (
amendment.platformOperatorRepresentative,
amendment.signedBlockTimestamp,
amendment.agreementUri,
last
);
}
pastAgreement keyboard_arrow_up
Source Code
function pastAgreement(uint256 amendmentIndex)
public
constant
returns (
address platformOperatorRepresentative,
uint256 signedBlockTimestamp,
string agreementUri,
uint256 index
)
{
SignedAgreement storage amendment = _amendments[amendmentIndex];
return (
amendment.platformOperatorRepresentative,
amendment.signedBlockTimestamp,
amendment.agreementUri,
amendmentIndex
);
}
agreementSignedAtBlock keyboard_arrow_up
issueForEuro keyboard_arrow_up
Modifiers help
only checks for the following:
acceptAgreement checks for the following:
Requirements help
One or more of the following:
-
the result of calling parentSnapshotId
must be less than
UNKNOWN VALUE
- OR
the result of calling parentToken
must be equal to
UNKNOWN VALUE
Source Code
function issueForEuro(uint256 euroUlps)
public
only(ROLE_NEUMARK_ISSUER)
acceptAgreement(msg.sender)
returns (uint256)
{
require(_totalEurUlps + euroUlps >= _totalEurUlps);
uint256 neumarkUlps = incremental(_totalEurUlps, euroUlps);
_totalEurUlps += euroUlps;
mGenerateTokens(msg.sender, neumarkUlps);
LogNeumarksIssued(msg.sender, euroUlps, neumarkUlps);
return neumarkUlps;
}
distribute keyboard_arrow_up
Modifiers help
only checks for the following:
acceptAgreement checks for the following:
Requirements help
One or more of the following:
-
the result of calling parentSnapshotId
must be less than
UNKNOWN VALUE
- OR
the result of calling parentToken
must be equal to
UNKNOWN VALUE
null
Source Code
function distribute(address to, uint256 neumarkUlps)
public
only(ROLE_NEUMARK_ISSUER)
acceptAgreement(to)
{
mTransfer(msg.sender, to, neumarkUlps);
}
burn keyboard_arrow_up
Modifiers help
only checks for the following:
Requirements help
One or more of the following:
-
the result of calling parentSnapshotId
must be less than
UNKNOWN VALUE
- OR
the result of calling parentToken
must be equal to
UNKNOWN VALUE
Source Code
function burn(uint256 neumarkUlps) public only(ROLE_NEUMARK_BURNER) {
burnPrivate(neumarkUlps, 0, _totalEurUlps);
}
burn keyboard_arrow_up
Modifiers help
only checks for the following:
Requirements help
One or more of the following:
-
the result of calling parentSnapshotId
must be less than
UNKNOWN VALUE
- OR
the result of calling parentToken
must be equal to
UNKNOWN VALUE
Source Code
function burn(
uint256 neumarkUlps,
uint256 minEurUlps,
uint256 maxEurUlps
) public only(ROLE_NEUMARK_BURNER) {
burnPrivate(neumarkUlps, minEurUlps, maxEurUlps);
}
enableTransfer keyboard_arrow_up
transferEnabled keyboard_arrow_up
totalEuroUlps keyboard_arrow_up
incremental keyboard_arrow_up
Requirements help
Source Code
function incremental(uint256 euroUlps)
public
constant
returns (uint256 neumarkUlps)
{
return incremental(_totalEurUlps, euroUlps);
}
Internal Functions
Internal functions are parts of the contract that can't be used directly, but instead are used by the public functions listed above.
internal Neumark.mOnTransfer keyboard_arrow_up
Modifiers help
acceptAgreement checks for the following:
Source Code
function mOnTransfer(
address from,
address, // to
uint256 // amount
) internal acceptAgreement(from) returns (bool allow) {
// must have transfer enabled or msg.sender is Neumark issuer
return
_transferEnabled ||
accessPolicy().allowed(msg.sender, ROLE_NEUMARK_ISSUER, this, msg.sig);
}
internal Neumark.mOnApprove keyboard_arrow_up
Modifiers help
acceptAgreement checks for the following:
Source Code
function mOnApprove(
address owner,
address, // spender,
uint256 // amount
) internal acceptAgreement(owner) returns (bool allow) {
return true;
}
internal Neumark.burnPrivate keyboard_arrow_up
Parameters help
Requirements help
One or more of the following:
-
the result of calling parentSnapshotId
must be less than
UNKNOWN VALUE
- OR
the result of calling parentToken
must be equal to
UNKNOWN VALUE
Source Code
function burnPrivate(
uint256 burnNeumarkUlps,
uint256 minEurUlps,
uint256 maxEurUlps
) private {
uint256 prevEuroUlps = _totalEurUlps;
// burn first in the token to make sure balance/totalSupply is not crossed
mDestroyTokens(msg.sender, burnNeumarkUlps);
_totalEurUlps = cumulativeInverse(totalSupply(), minEurUlps, maxEurUlps);
// actually may overflow on non-monotonic inverse
assert(prevEuroUlps >= _totalEurUlps);
uint256 euroUlps = prevEuroUlps - _totalEurUlps;
LogNeumarksBurned(msg.sender, euroUlps, burnNeumarkUlps);
}
internal AccessControlled.AccessControlled keyboard_arrow_up
Requirements help
UNKNOWN VALUE
must not be equal to
0x0
Source Code
function AccessControlled(IAccessPolicy policy) internal {
require(address(policy) != 0x0);
_accessPolicy = policy;
}
internal Agreement.Agreement keyboard_arrow_up
Requirements help
Source Code
function Agreement(IAccessPolicy accessPolicy, IEthereumForkArbiter forkArbiter)
internal
AccessControlled(accessPolicy)
{
require(forkArbiter != IEthereumForkArbiter(0x0));
ETHEREUM_FORK_ARBITER = forkArbiter;
}
internal AccessControlled.AccessControlled keyboard_arrow_up
Requirements help
UNKNOWN VALUE
must not be equal to
0x0
Source Code
function AccessControlled(IAccessPolicy policy) internal {
require(address(policy) != 0x0);
_accessPolicy = policy;
}
internal DailyAndSnapshotable.DailyAndSnapshotable keyboard_arrow_up
Source Code
function DailyAndSnapshotable(uint256 start) internal {
// 0 is invalid value as we are past unix epoch
if (start > 0) {
uint256 dayBase = snapshotAt(block.timestamp);
require(start >= dayBase);
// dayBase + 2**128 will not overflow as it is based on block.timestamp
require(start < dayBase + 2**128);
_currentSnapshotId = start;
}
}
internal DailyAndSnapshotable.mCurrentSnapshotId keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function mCurrentSnapshotId() internal returns (uint256) {
uint256 dayBase = 2**128 * (block.timestamp / 1 days);
// New day has started
if (dayBase > _currentSnapshotId) {
_currentSnapshotId = dayBase;
LogSnapshotCreated(dayBase);
}
return _currentSnapshotId;
}
internal MSnapshotPolicy.mCurrentSnapshotId keyboard_arrow_up
internal StandardSnapshotToken.StandardSnapshotToken keyboard_arrow_up
Source Code
function StandardSnapshotToken(
IClonedTokenParent parentToken,
uint256 parentSnapshotId
)
internal
MintableSnapshotToken(parentToken, parentSnapshotId)
TokenAllowance()
{}
internal MintableSnapshotToken.MintableSnapshotToken keyboard_arrow_up
Source Code
function MintableSnapshotToken(
IClonedTokenParent parentToken,
uint256 parentSnapshotId
) internal BasicSnapshotToken(parentToken, parentSnapshotId) {}
internal MintableSnapshotToken.mGenerateTokens keyboard_arrow_up
Requirements help
One or more of the following:
-
the result of calling parentSnapshotId
must be less than
UNKNOWN VALUE
- OR
the result of calling parentToken
must be equal to
UNKNOWN VALUE
Source Code
function mGenerateTokens(address owner, uint256 amount) internal {
// never create for address 0
require(owner != address(0));
// block changes in clone that points to future/current snapshots of patent token
require(
parentToken() == address(0) ||
parentSnapshotId() < parentToken().currentSnapshotId()
);
uint256 curTotalSupply = totalSupply();
uint256 newTotalSupply = curTotalSupply + amount;
require(newTotalSupply >= curTotalSupply); // Check for overflow
uint256 previousBalanceTo = balanceOf(owner);
uint256 newBalanceTo = previousBalanceTo + amount;
assert(newBalanceTo >= previousBalanceTo); // Check for overflow
setValue(_totalSupplyValues, newTotalSupply);
setValue(_balances[owner], newBalanceTo);
Transfer(0, owner, amount);
}
internal MintableSnapshotToken.mDestroyTokens keyboard_arrow_up
Requirements help
One or more of the following:
-
the result of calling parentSnapshotId
must be less than
UNKNOWN VALUE
- OR
the result of calling parentToken
must be equal to
UNKNOWN VALUE
Source Code
function mDestroyTokens(address owner, uint256 amount) internal {
// block changes in clone that points to future/current snapshots of patent token
require(
parentToken() == address(0) ||
parentSnapshotId() < parentToken().currentSnapshotId()
);
uint256 curTotalSupply = totalSupply();
require(curTotalSupply >= amount);
uint256 previousBalanceFrom = balanceOf(owner);
require(previousBalanceFrom >= amount);
uint256 newTotalSupply = curTotalSupply - amount;
uint256 newBalanceFrom = previousBalanceFrom - amount;
setValue(_totalSupplyValues, newTotalSupply);
setValue(_balances[owner], newBalanceFrom);
Transfer(owner, 0, amount);
}
internal BasicSnapshotToken.BasicSnapshotToken keyboard_arrow_up
Source Code
function BasicSnapshotToken(
IClonedTokenParent parentToken,
uint256 parentSnapshotId
) internal Snapshot() {
PARENT_TOKEN = parentToken;
if (parentToken == address(0)) {
require(parentSnapshotId == 0);
} else {
if (parentSnapshotId == 0) {
require(parentToken.currentSnapshotId() > 0);
PARENT_SNAPSHOT_ID = parentToken.currentSnapshotId() - 1;
} else {
PARENT_SNAPSHOT_ID = parentSnapshotId;
}
}
}
internal BasicSnapshotToken.balanceOfAtInternal keyboard_arrow_up
Source Code
function balanceOfAtInternal(address owner, uint256 snapshotId)
internal
constant
returns (uint256)
{
Values[] storage values = _balances[owner];
// If there is a value, return it, reverts if value is in the future
if (hasValueAt(values, snapshotId)) {
return getValueAt(values, snapshotId, 0);
}
// Try parent contract at or before the fork
if (PARENT_TOKEN != address(0)) {
uint256 earlierSnapshotId = PARENT_SNAPSHOT_ID > snapshotId
? snapshotId
: PARENT_SNAPSHOT_ID;
return PARENT_TOKEN.balanceOfAt(owner, earlierSnapshotId);
}
// Default to an empty balance
return 0;
}
internal BasicSnapshotToken.mTransfer keyboard_arrow_up
Requirements help
One or more of the following:
-
the result of calling parentSnapshotId
must be less than
UNKNOWN VALUE
- OR
the result of calling parentToken
must be equal to
UNKNOWN VALUE
null
Source Code
function mTransfer(
address from,
address to,
uint256 amount
) internal {
// never send to address 0
require(to != address(0));
// block transfers in clone that points to future/current snapshots of patent token
require(
parentToken() == address(0) ||
parentSnapshotId() < parentToken().currentSnapshotId()
);
// Alerts the token controller of the transfer
require(mOnTransfer(from, to, amount));
// If the amount being transfered is more than the balance of the
// account the transfer reverts
var previousBalanceFrom = balanceOf(from);
require(previousBalanceFrom >= amount);
// First update the balance array with the new value for the address
// sending the tokens
uint256 newBalanceFrom = previousBalanceFrom - amount;
setValue(_balances[from], newBalanceFrom);
// Then update the balance array with the new value for the address
// receiving the tokens
uint256 previousBalanceTo = balanceOf(to);
uint256 newBalanceTo = previousBalanceTo + amount;
assert(newBalanceTo >= previousBalanceTo); // Check for overflow
setValue(_balances[to], newBalanceTo);
// An event to make the transfer easy to find on the blockchain
Transfer(from, to, amount);
}
internal MTokenTransfer.mTransfer keyboard_arrow_up
internal MTokenTransferController.mOnTransfer keyboard_arrow_up
internal Snapshot.hasValue keyboard_arrow_up
internal Snapshot.hasValueAt keyboard_arrow_up
Requirements help
Source Code
function hasValueAt(Values[] storage values, uint256 snapshotId)
internal
constant
returns (bool)
{
require(snapshotId <= mCurrentSnapshotId());
return values.length > 0 && values[0].snapshotId <= snapshotId;
}
internal Snapshot.getValue keyboard_arrow_up
Source Code
function getValue(Values[] storage values, uint256 defaultValue)
internal
constant
returns (uint256)
{
if (values.length == 0) {
return defaultValue;
} else {
uint256 last = values.length - 1;
return values[last].value;
}
}
internal Snapshot.getValueAt keyboard_arrow_up
Requirements help
Source Code
function getValueAt(
Values[] storage values,
uint256 snapshotId,
uint256 defaultValue
) internal constant returns (uint256) {
require(snapshotId <= mCurrentSnapshotId());
// Empty value
if (values.length == 0) {
return defaultValue;
}
// Shortcut for the out of bounds snapshots
uint256 last = values.length - 1;
uint256 lastSnapshot = values[last].snapshotId;
if (snapshotId >= lastSnapshot) {
return values[last].value;
}
uint256 firstSnapshot = values[0].snapshotId;
if (snapshotId < firstSnapshot) {
return defaultValue;
}
// Binary search of the value in the array
uint256 min = 0;
uint256 max = last;
while (max > min) {
uint256 mid = (max + min + 1) / 2;
// must always return lower indice for approximate searches
if (values[mid].snapshotId <= snapshotId) {
min = mid;
} else {
max = mid - 1;
}
}
return values[min].value;
}
internal Snapshot.setValue keyboard_arrow_up
Source Code
function setValue(Values[] storage values, uint256 value) internal {
// TODO: simplify or break into smaller functions
uint256 currentSnapshotId = mCurrentSnapshotId();
// Always create a new entry if there currently is no value
bool empty = values.length == 0;
if (empty) {
// Create a new entry
values.push(Values({snapshotId: currentSnapshotId, value: value}));
return;
}
uint256 last = values.length - 1;
bool hasNewSnapshot = values[last].snapshotId < currentSnapshotId;
if (hasNewSnapshot) {
// Do nothing if the value was not modified
bool unmodified = values[last].value == value;
if (unmodified) {
return;
}
// Create new entry
values.push(Values({snapshotId: currentSnapshotId, value: value}));
} else {
// We are updating the currentSnapshotId
bool previousUnmodified = last > 0 && values[last - 1].value == value;
if (previousUnmodified) {
// Remove current snapshot if current value was set to previous value
delete values[last];
values.length--;
return;
}
// Overwrite next snapshot entry
values[last].value = value;
}
}
internal MSnapshotPolicy.mCurrentSnapshotId keyboard_arrow_up
internal MTokenMint.mGenerateTokens keyboard_arrow_up
internal MTokenMint.mDestroyTokens keyboard_arrow_up
internal TokenAllowance.TokenAllowance keyboard_arrow_up
internal MTokenTransfer.mTransfer keyboard_arrow_up
internal MTokenAllowanceController.mOnApprove keyboard_arrow_up
internal IsContract.isContract keyboard_arrow_up
internal AccessControlled.AccessControlled keyboard_arrow_up
Requirements help
UNKNOWN VALUE
must not be equal to
0x0
Source Code
function AccessControlled(IAccessPolicy policy) internal {
require(address(policy) != 0x0);
_accessPolicy = policy;
}