Safe, simple, flexible building-blocks for smart-contract systems.
ds-auth
ds-guard
ds-roles
ds-token
ds-vault
ds-cache
ds-value
ds-exec
ds-math
ds-note
ds-proxy
ds-stop
ds-thing
ds-multisig
Safe Arithmetic
DS-Math provides arithmetic functions for the common numerical primitive types
of Solidity. You can safely add, subtract, multiply, and divide uint
numbers
without fear of integer overflow. You can also find the minimum and maximum of
two numbers.
Additionally, this package provides arithmetic functions for new two higher level numerical concepts called wad (18 decimals) and ray (27 decimals). These are used to represent fixed-point decimal numbers.
A wad is a decimal number with 18 digits of precision and a ray is a decimal
number with 27 digits of precision. These functions are necessary to account for
the difference between how integer arithmetic behaves normally, and how decimal
arithmetic should actually work. A brief example using wmul
, which returns the
product of a wad and another number:
1.1 * 2.2 == 2.42
//Regular integer arithmetic adds orders of magnitude:
110 * 220 == 24200
// Wad arithmetic does not add orders of magnitude:
wmul(1.1 ether, 2.2 ether) == 2.42 ether
The standard functions are the uint
set, so their function names are not
prefixed: add
, sub
, mul
, min
, and max
. There is no div
function, as
divide-by-zero checking is built into the Solidity compiler.
The int
functions have an i
prefix: imin
, and imax
.
Wad functions have a w
prefix: wmul
, wdiv
.
Ray functions have a r
prefix: rmul
, rdiv
, rpow
.
add
Return x + y
or an exception in case of uint
overflow.
sub
Return x - y
or an exception in case of uint
overflow.
mul
Return x * y
or an exception in case of uint
overflow.
min
Return the smaller number of x
and y
.
max
Return the larger number of x
and y
.
imin
Return the smaller number of x
and y
.
imax
Return the larger number of x
and y
.
wmul
Multiply two Wads and return a new Wad with the correct level of precision. A Wad is a decimal number with 18 digits of precision that is being represented as an integer.
wdiv
Divide two Wads and return a new Wad with the correct level of precision. A Wad is a decimal number with 18 digits of precision that is being represented as an integer.
rmul
Multiply two Rays and return a new Ray with the correct level of precision. A Ray is a decimal number with 27 digits of precision that is being represented as an integer.
rdiv
Divide two Rays and return a new Ray with the correct level of precision. A Ray is a decimal number with 27 digits of precision that is being represented as an integer.
rpow
Raise a Ray to the n^th power and return a new Ray with the correct level of precision. A Ray is a decimal number with 27 digits of precision that is being represented as an integer.
/// math.sol -- mixin for inline numerical wizardry
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity ^0.4.13;
contract DSMath {
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x);
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x);
}
function mul(uint x, uint y) internal pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x);
}
function min(uint x, uint y) internal pure returns (uint z) {
return x <= y ? x : y;
}
function max(uint x, uint y) internal pure returns (uint z) {
return x >= y ? x : y;
}
function imin(int x, int y) internal pure returns (int z) {
return x <= y ? x : y;
}
function imax(int x, int y) internal pure returns (int z) {
return x >= y ? x : y;
}
uint constant WAD = 10 ** 18;
uint constant RAY = 10 ** 27;
function wmul(uint x, uint y) internal pure returns (uint z) {
z = add(mul(x, y), WAD / 2) / WAD;
}
function rmul(uint x, uint y) internal pure returns (uint z) {
z = add(mul(x, y), RAY / 2) / RAY;
}
function wdiv(uint x, uint y) internal pure returns (uint z) {
z = add(mul(x, WAD), y / 2) / y;
}
function rdiv(uint x, uint y) internal pure returns (uint z) {
z = add(mul(x, RAY), y / 2) / y;
}
// This famous algorithm is called "exponentiation by squaring"
// and calculates x^n with x as fixed-point and n as regular unsigned.
//
// It's O(log n), instead of O(n) for naive repeated multiplication.
//
// These facts are why it works:
//
// If n is even, then x^n = (x^2)^(n/2).
// If n is odd, then x^n = x * x^(n-1),
// and applying the equation for even x gives
// x^n = x * (x^2)^((n-1) / 2).
//
// Also, EVM division is flooring and
// floor[(n-1) / 2] = floor[n / 2].
//
function rpow(uint x, uint n) internal pure returns (uint z) {
z = n % 2 != 0 ? x : RAY;
for (n /= 2; n != 0; n /= 2) {
x = rmul(x, x);
if (n % 2 != 0) {
z = rmul(z, x);
}
}
}
}
We believe that the free software movement is the most important cultural predecessor to the modern-day renaissance in decentralized technologies.
To catalyze the growth of this ecosystem, and to empower hackers to participate, we’re building a comprehensive suite of blockchain-oriented developer tools in the spirit of the Unix philosophy.
Dapp is all you need to start developing for Ethereum. It creates new dapps, runs Solidity unit tests, debugs, deploys, launches testnets, and more.
Seth is a handy tool for slicing and dicing transactions, querying the blockchain, converting between data formats, performing remote calls, and other everyday tasks.
Hevm is our own EVM
implementation with a nimble terminal-based Solidity debugger.
It’s used for dapp test
and dapp debug
.
We also maintain Dappsys, an audited collection of smart contract building blocks designed to complement each other. They include;
ds-token
—
a generic EIP-20 coin;
ds-group
—
a multisig;
ds-guard
—
a flexible authority rule;
ds-proxy
—
a transaction proxy; and
ds-cache
—
a store of expiring values.
Using these proven parts lets us focus on the novel features of the systems we develop. We share Dappsys to benefit the smart contract ecosystem.