1
+ pragma solidity ^ 0.5.12 ;
2
+
3
+ import { PotAbstract } from "./PotAbstract.sol " ;
4
+
5
+ // https://github.com/makerdao/dss/blob/master/src/pot.sol
6
+ contract PotHelper {
7
+
8
+ PotAbstract pa;
9
+
10
+ constructor (address pot ) public {
11
+ pa = PotAbstract (pot);
12
+ }
13
+
14
+ // https://github.com/makerdao/dss/blob/master/src/pot.sol#L79
15
+ uint256 constant ONE = 10 ** 27 ;
16
+
17
+ function mul (uint x , uint y ) internal pure returns (uint z ) {
18
+ require (y == 0 || (z = x * y) / y == x);
19
+ }
20
+
21
+ function rmul (uint x , uint y ) internal pure returns (uint z ) {
22
+ z = mul (x, y) / ONE;
23
+ }
24
+
25
+ function rpow (uint x , uint n , uint base ) internal pure returns (uint z ) {
26
+ assembly {
27
+ switch x case 0 {switch n case 0 {z := base} default {z := 0 }}
28
+ default {
29
+ switch mod (n, 2 ) case 0 { z := base } default { z := x }
30
+ let half := div (base, 2 ) // for rounding.
31
+ for { n := div (n, 2 ) } n { n := div (n,2 ) } {
32
+ let xx := mul (x, x)
33
+ if iszero (eq (div (xx, x), x)) { revert (0 ,0 ) }
34
+ let xxRound := add (xx, half)
35
+ if lt (xxRound, xx) { revert (0 ,0 ) }
36
+ x := div (xxRound, base)
37
+ if mod (n,2 ) {
38
+ let zx := mul (z, x)
39
+ if and (iszero (iszero (x)), iszero (eq (div (zx, x), z))) { revert (0 ,0 ) }
40
+ let zxRound := add (zx, half)
41
+ if lt (zxRound, zx) { revert (0 ,0 ) }
42
+ z := div (zxRound, base)
43
+ }
44
+ }
45
+ }
46
+ }
47
+ }
48
+
49
+ // View function for calculating value of chi iff drip() is called in the same block.
50
+ function drop () external view returns (uint256 ) {
51
+ if (now == pa.rho ()) return pa.chi ();
52
+ return rmul (rpow (pa.dsr (), now - pa.rho (), ONE), pa.chi ());
53
+ }
54
+
55
+ // Pass the Pot Abstract for additional operations
56
+ function pot () external view returns (PotAbstract) {
57
+ return pa;
58
+ }
59
+ }
0 commit comments