UNPKG

@gnosis.pm/util-contracts

Version:
695 lines (694 loc) 1.38 MB
{ "contractName": "GnosisMath", "abi": [ { "inputs": [], "name": "LN2", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "LOG2_E", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "ONE", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "int256", "name": "x", "type": "int256" } ], "name": "exp", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "pure", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "x", "type": "uint256" } ], "name": "ln", "outputs": [ { "internalType": "int256", "name": "", "type": "int256" } ], "stateMutability": "pure", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "x", "type": "uint256" } ], "name": "floorLog2", "outputs": [ { "internalType": "int256", "name": "lo", "type": "int256" } ], "stateMutability": "pure", "type": "function" }, { "inputs": [ { "internalType": "int256[]", "name": "nums", "type": "int256[]" } ], "name": "max", "outputs": [ { "internalType": "int256", "name": "maxNum", "type": "int256" } ], "stateMutability": "pure", "type": "function" } ], "metadata": "{\"compiler\":{\"version\":\"0.7.5+commit.eb77ed08\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"LN2\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LOG2_E\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ONE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"x\",\"type\":\"int256\"}],\"name\":\"exp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"floorLog2\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"lo\",\"type\":\"int256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"ln\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256[]\",\"name\":\"nums\",\"type\":\"int256[]\"}],\"name\":\"max\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"maxNum\",\"type\":\"int256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Alan Lu - <alan.lu@gnosis.pm>Stefan George - <stefan@gnosis.pm>\",\"kind\":\"dev\",\"methods\":{\"exp(int256)\":{\"details\":\"Returns natural exponential function value of given x\",\"params\":{\"x\":\"x\"},\"returns\":{\"_0\":\"e**x\"}},\"floorLog2(uint256)\":{\"details\":\"Returns base 2 logarithm value of given x\",\"params\":{\"x\":\"x\"},\"returns\":{\"lo\":\"- logarithmic value\"}},\"ln(uint256)\":{\"details\":\"Returns natural logarithm value of given x\",\"params\":{\"x\":\"x\"},\"returns\":{\"_0\":\"ln(x)\"}},\"max(int256[])\":{\"details\":\"Returns maximum of an array\",\"params\":{\"nums\":\"Numbers to look through\"},\"returns\":{\"maxNum\":\"- Maximum number\"}}},\"title\":\"Math library - Allows calculation of logarithmic and exponential functions\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"/Users/bensniff/Projects/gnosis/util-contracts/contracts/Math.sol\":\"GnosisMath\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"/Users/bensniff/Projects/gnosis/util-contracts/contracts/Math.sol\":{\"keccak256\":\"0xd6411e92ade55d077dc3cab8a7ef2a2a16c87e7f00b709de3d16e206b3a26828\",\"license\":\"LGPL-3.0-only\",\"urls\":[\"bzz-raw://5fe697b4c22396abf00835cfd358216370c3cda4f2fbf4ff0f76f87aab0b7460\",\"dweb:/ipfs/Qmb9DWeY4HpCXwLiFTx5qEDnh4cK6Lct6X7mcnY6sTzGm9\"]}},\"version\":1}", "bytecode": "0x61079f610026600b82828239805160001a60731461001957fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100875760003560e01c806345b8bafc1161006557806345b8bafc146100cb578063c2ee3a08146100e8578063ccc13814146100f0578063e46751e31461019357610087565b8063027806771461008c57806324902e24146100a657806324d4e90a146100ae575b600080fd5b6100946101b0565b60408051918252519081900360200190f35b6100946101bc565b610094600480360360208110156100c457600080fd5b50356101c9565b610094600480360360208110156100e157600080fd5b5035610426565b610094610495565b6100946004803603602081101561010657600080fd5b81019060208101813564010000000081111561012157600080fd5b82018360208201111561013357600080fd5b8035906020019184602083028401116401000000008311171561015557600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061049d945050505050565b610094600480360360208110156101a957600080fd5b50356104fe565b67b17217f7d1cf79ac81565b680171547652b82fe17781565b60008082116101d757600080fd5b60006101e283610426565b90506000808212156101fc578160000384901b9050610201565b5082811c5b6000600160401b8201600160401b808403028161021a57fe5b059050806000600160401b828181800205028161023357fe5b0590506003810582019150600160401b83600160401b8584028161025357fe5b05028161025c57fe5b0590506005810582019150600160401b83600160401b8584028161027c57fe5b05028161028557fe5b0590506007810582019150600160401b83600160401b858402816102a557fe5b0502816102ae57fe5b0590506009810582019150600160401b83600160401b858402816102ce57fe5b0502816102d757fe5b059050600b810582019150600160401b83600160401b858402816102f757fe5b05028161030057fe5b059050600d810582019150600160401b83600160401b8584028161032057fe5b05028161032957fe5b059050600f810582019150600160401b83600160401b8584028161034957fe5b05028161035257fe5b0590506011810582019150600160401b83600160401b8584028161037257fe5b05028161037b57fe5b0590506013810582019150600160401b83600160401b8584028161039b57fe5b0502816103a457fe5b0590506015810582019150600160401b83600160401b858402816103c457fe5b0502816103cd57fe5b0590506017810582019150600160401b83600160401b858402816103ed57fe5b0502816103f657fe5b05905060198105919091019060028202680171547652b82fe177600160801b87020501955050505050505b919050565b603f1960c1608160011d5b8183600101121561048e576000811280156104555750600160401b8160000385901b105b806104715750600081121580156104715750600160401b84821c105b1561047e57809150610482565b8092505b5080820160011d610431565b5050919050565b600160401b81565b6000808251116104ac57600080fd5b50600160ff1b60005b82518110156104f857818382815181106104cb57fe5b602002602001015113156104f0578281815181106104e557fe5b602002602001015191505b6001016104b5565b50919050565b600068851591f9dd5b9b40d782131561051657600080fd5b682c5c85fdf473de6af21982121561053057506000610421565b67b17217f7d1cf79ac600160401b830205915060008060008412610560575050600160401b808305908307610586565b6001600160401b8505039150600160401b846000038161057c57fe5b07600160401b0390505b80600160401b8067b17217f7d1cf79ab83020401600160401b828402049150600160401b673d7f7bff058b1d5083020401600160401b828402049150600160401b670e35846b82505fc583020401600160401b828402049150600160401b670276556df749cee583020401600160401b828402049150600160401b665761ff9e299cc483020401600160401b828402049150600160401b660a184897c363c383020401600160401b828402049150600160401b65ffe5fe2c458683020401600160401b828402049150600160401b65162c0223a5c883020401600160401b828402049150600160401b6501b5253d395e83020401600160401b828402049150600160401b641e4cf5158b83020401600160401b828402049150600160401b6401e8cac73583020401600160401b828402049150600160401b631c3bd65083020401600160401b828402049150600160401b630181619383020401600160401b828402049150600160401b6213149683020401600160401b828402049150600160401b61e1b783020401600160401b828402049150600160401b6109c783020401600084126107575761010084900381901c1561074a57600019945050505050610421565b90921b9250610421915050565b8360000381901c94505050505061042156fea2646970667358221220354b60830455f6845af1329814a344440500e9fac8ca1c11044c367220c9961a64736f6c63430007050033", "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600436106100875760003560e01c806345b8bafc1161006557806345b8bafc146100cb578063c2ee3a08146100e8578063ccc13814146100f0578063e46751e31461019357610087565b8063027806771461008c57806324902e24146100a657806324d4e90a146100ae575b600080fd5b6100946101b0565b60408051918252519081900360200190f35b6100946101bc565b610094600480360360208110156100c457600080fd5b50356101c9565b610094600480360360208110156100e157600080fd5b5035610426565b610094610495565b6100946004803603602081101561010657600080fd5b81019060208101813564010000000081111561012157600080fd5b82018360208201111561013357600080fd5b8035906020019184602083028401116401000000008311171561015557600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061049d945050505050565b610094600480360360208110156101a957600080fd5b50356104fe565b67b17217f7d1cf79ac81565b680171547652b82fe17781565b60008082116101d757600080fd5b60006101e283610426565b90506000808212156101fc578160000384901b9050610201565b5082811c5b6000600160401b8201600160401b808403028161021a57fe5b059050806000600160401b828181800205028161023357fe5b0590506003810582019150600160401b83600160401b8584028161025357fe5b05028161025c57fe5b0590506005810582019150600160401b83600160401b8584028161027c57fe5b05028161028557fe5b0590506007810582019150600160401b83600160401b858402816102a557fe5b0502816102ae57fe5b0590506009810582019150600160401b83600160401b858402816102ce57fe5b0502816102d757fe5b059050600b810582019150600160401b83600160401b858402816102f757fe5b05028161030057fe5b059050600d810582019150600160401b83600160401b8584028161032057fe5b05028161032957fe5b059050600f810582019150600160401b83600160401b8584028161034957fe5b05028161035257fe5b0590506011810582019150600160401b83600160401b8584028161037257fe5b05028161037b57fe5b0590506013810582019150600160401b83600160401b8584028161039b57fe5b0502816103a457fe5b0590506015810582019150600160401b83600160401b858402816103c457fe5b0502816103cd57fe5b0590506017810582019150600160401b83600160401b858402816103ed57fe5b0502816103f657fe5b05905060198105919091019060028202680171547652b82fe177600160801b87020501955050505050505b919050565b603f1960c1608160011d5b8183600101121561048e576000811280156104555750600160401b8160000385901b105b806104715750600081121580156104715750600160401b84821c105b1561047e57809150610482565b8092505b5080820160011d610431565b5050919050565b600160401b81565b6000808251116104ac57600080fd5b50600160ff1b60005b82518110156104f857818382815181106104cb57fe5b602002602001015113156104f0578281815181106104e557fe5b602002602001015191505b6001016104b5565b50919050565b600068851591f9dd5b9b40d782131561051657600080fd5b682c5c85fdf473de6af21982121561053057506000610421565b67b17217f7d1cf79ac600160401b830205915060008060008412610560575050600160401b808305908307610586565b6001600160401b8505039150600160401b846000038161057c57fe5b07600160401b0390505b80600160401b8067b17217f7d1cf79ab83020401600160401b828402049150600160401b673d7f7bff058b1d5083020401600160401b828402049150600160401b670e35846b82505fc583020401600160401b828402049150600160401b670276556df749cee583020401600160401b828402049150600160401b665761ff9e299cc483020401600160401b828402049150600160401b660a184897c363c383020401600160401b828402049150600160401b65ffe5fe2c458683020401600160401b828402049150600160401b65162c0223a5c883020401600160401b828402049150600160401b6501b5253d395e83020401600160401b828402049150600160401b641e4cf5158b83020401600160401b828402049150600160401b6401e8cac73583020401600160401b828402049150600160401b631c3bd65083020401600160401b828402049150600160401b630181619383020401600160401b828402049150600160401b6213149683020401600160401b828402049150600160401b61e1b783020401600160401b828402049150600160401b6109c783020401600084126107575761010084900381901c1561074a57600019945050505050610421565b90921b9250610421915050565b8360000381901c94505050505061042156fea2646970667358221220354b60830455f6845af1329814a344440500e9fac8ca1c11044c367220c9961a64736f6c63430007050033", "immutableReferences": {}, "generatedSources": [], "deployedGeneratedSources": [], "sourceMap": "242:9256:3:-:0;;;;;;;;;;;;;;;;;;;;;;;;;", "deployedSourceMap": "242:9256:3:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;398:45;;;:::i;:::-;;;;;;;;;;;;;;;;449:49;;;:::i;3538:1779::-;;;;;;;;;;;;;;;;-1:-1:-1;3538:1779:3;;:::i;5436:429::-;;;;;;;;;;;;;;;;-1:-1:-1;5436:429:3;;:::i;346:46::-;;;:::i;5996:221::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5996:221:3;;-1:-1:-1;5996:221:3;;-1:-1:-1;;;;;5996:221:3:i;652:2783::-;;;;;;;;;;;;;;;;-1:-1:-1;652:2783:3;;:::i;398:45::-;425:18;398:45;:::o;449:49::-;479:19;449:49;:::o;3538:1779::-;3579:3;3606:1;3602;:5;3594:14;;;;;;3662:9;3674:12;3684:1;3674:9;:12::i;:::-;3662:24;;3696:5;3723:1;3715:5;:9;3711:81;;;3745:5;3744:6;;3734:1;:17;;3726:26;;3711:81;;;-1:-1:-1;3775:16:3;;;3711:81;4006:8;-1:-1:-1;;;4046:1:3;:12;-1:-1:-1;;;373:19:3;4018:1;:12;4017:25;:42;;;;;;;-1:-1:-1;4017:42:3;4069:11;-1:-1:-1;;;4017:42:3;373:19;4111:11;;;:22;:29;:40;;;;;;;-1:-1:-1;4182:1:3;4111:40;4172:11;4161:22;;;;-1:-1:-1;;;4231:4:3;-1:-1:-1;;;4213:4:3;4203:7;:14;:25;;;;;;:32;:43;;;;;;;-1:-1:-1;4277:1:3;4203:43;4267:11;4256:22;;;;-1:-1:-1;;;4326:4:3;-1:-1:-1;;;4308:4:3;4298:7;:14;:25;;;;;;:32;:43;;;;;;;-1:-1:-1;4372:1:3;4298:43;4362:11;4351:22;;;;-1:-1:-1;;;4421:4:3;-1:-1:-1;;;4403:4:3;4393:7;:14;:25;;;;;;:32;:43;;;;;;;-1:-1:-1;4467:1:3;4393:43;4457:11;4446:22;;;;-1:-1:-1;;;4516:4:3;-1:-1:-1;;;4498:4:3;4488:7;:14;:25;;;;;;:32;:43;;;;;;;-1:-1:-1;4562:2:3;4488:43;4552:12;4541:23;;;;-1:-1:-1;;;4612:4:3;-1:-1:-1;;;4594:4:3;4584:7;:14;:25;;;;;;:32;:43;;;;;;;-1:-1:-1;4658:2:3;4584:43;4648:12;4637:23;;;;-1:-1:-1;;;4708:4:3;-1:-1:-1;;;4690:4:3;4680:7;:14;:25;;;;;;:32;:43;;;;;;;-1:-1:-1;4754:2:3;4680:43;4744:12;4733:23;;;;-1:-1:-1;;;4804:4:3;-1:-1:-1;;;4786:4:3;4776:7;:14;:25;;;;;;:32;:43;;;;;;;-1:-1:-1;4850:2:3;4776:43;4840:12;4829:23;;;;-1:-1:-1;;;4900:4:3;-1:-1:-1;;;4882:4:3;4872:7;:14;:25;;;;;;:32;:43;;;;;;;-1:-1:-1;4946:2:3;4872:43;4936:12;4925:23;;;;-1:-1:-1;;;4996:4:3;-1:-1:-1;;;4978:4:3;4968:7;:14;:25;;;;;;:32;:43;;;;;;;-1:-1:-1;5042:2:3;4968:43;5032:12;5021:23;;;;-1:-1:-1;;;5092:4:3;-1:-1:-1;;;5074:4:3;5064:7;:14;:25;;;;;;:32;:43;;;;;;;-1:-1:-1;5138:2:3;5064:43;5128:12;5117:23;;;;-1:-1:-1;;;5188:4:3;-1:-1:-1;;;5170:4:3;5160:7;:14;:25;;;;;;:32;:43;;;;;;;-1:-1:-1;5234:2:3;5160:43;5224:12;5213:23;;;;;5299:1;:11;;479:19;-1:-1:-1;;;5253:29:3;;:43;:57;5246:64;;;;;;;3538:1779;;;;:::o;5436:429::-;-1:-1:-1;;5529:3:3;5646:7;5658:1;5645:14;5669:190;5687:2;5677;5682:1;5677:6;5676:13;5669:190;;;5715:1;5709:3;:7;:32;;;;;-1:-1:-1;;;5731:3:3;5730:4;;5720:1;:15;;:21;5709:32;:68;;;;5752:1;5745:3;:8;;:32;;;;-1:-1:-1;;;;5757:14:3;;;:20;5745:32;5705:109;;;5784:3;5779:8;;5705:109;;;5811:3;5806:8;;5705:109;-1:-1:-1;5835:7:3;;;5847:1;5834:14;5669:190;;;5436:429;;;;;:::o;346:46::-;-1:-1:-1;;;346:46:3;:::o;5996:221::-;6049:10;6093:1;6079:4;:11;:15;6071:24;;;;;;-1:-1:-1;;;;6138:6:3;6133:77;6154:4;:11;6150:1;:15;6133:77;;;6186:6;6176:4;6181:1;6176:7;;;;;;;;;;;;;;:16;6172:38;;;6203:4;6208:1;6203:7;;;;;;;;;;;;;;6194:16;;6172:38;6167:3;;6133:77;;;;5996:221;;;:::o;652:2783::-;693:4;841:22;836:1;:27;;828:36;;;;;;-1:-1:-1;;988:1:3;:26;984:40;;;-1:-1:-1;1023:1:3;1016:8;;984:40;425:18;-1:-1:-1;;;1078:12:3;;:23;1074:27;;1237:9;1256:6;1281:1;1276;:6;1272:191;;-1:-1:-1;;;;;1306:12:3;;;;1341;;1272:191;;;1408:1;-1:-1:-1;;;1393:1:3;:12;:16;1385:24;;-1:-1:-1;;;1439:1:3;1438:2;;:13;;;;;;-1:-1:-1;;;1427:25:3;1423:29;;1272:191;2010:1;-1:-1:-1;;;373:19:3;2058:18;:25;;:31;2048:41;-1:-1:-1;;;2106:8:3;;;:14;;-1:-1:-1;;;;2140:18:3;:25;;:31;2130:41;-1:-1:-1;;;2188:8:3;;;:14;;-1:-1:-1;;;;2222:17:3;:24;;:30;2212:40;-1:-1:-1;;;2269:8:3;;;:14;;-1:-1:-1;;;;2303:17:3;:24;;:30;2293:40;-1:-1:-1;;;2350:8:3;;;:14;;-1:-1:-1;;;;2384:16:3;:23;;:29;2374:39;-1:-1:-1;;;2430:8:3;;;:14;;-1:-1:-1;;;;2464:15:3;:22;;:28;2454:38;-1:-1:-1;;;2509:8:3;;;:14;;-1:-1:-1;;;;2543:14:3;:21;;:27;2533:37;-1:-1:-1;;;2587:8:3;;;:14;;-1:-1:-1;;;;2621:14:3;:21;;:27;2611:37;-1:-1:-1;;;2665:8:3;;;:14;;-1:-1:-1;;;;2699:13:3;:20;;:26;2689:36;-1:-1:-1;;;2742:8:3;;;:14;;-1:-1:-1;;;;2776:12:3;:19;;:25;2766:35;-1:-1:-1;;;2818:8:3;;;:14;;-1:-1:-1;;;;2852:11:3;:18;;:24;2842:34;-1:-1:-1;;;2893:8:3;;;:14;;-1:-1:-1;;;;2927:10:3;:17;;:23;2917:33;-1:-1:-1;;;2967:8:3;;;:14;;-1:-1:-1;;;;3001:9:3;:16;;:22;2991:32;-1:-1:-1;;;3040:8:3;;;:14;;-1:-1:-1;;;;3074:8:3;:15;;:21;3064:31;-1:-1:-1;;;3112:8:3;;;:14;;-1:-1:-1;;;;3146:6:3;:13;;:19;3136:29;-1:-1:-1;;;3182:8:3;;;:14;;-1:-1:-1;;;;3216:5:3;:12;;:18;3206:28;3257:1;3248:10;;3244:184;;3294:3;3289:23;;;3278:35;;;:39;3274:66;;-1:-1:-1;;3319:21:3;;;;;;;;3274:66;3361:21;;;;-1:-1:-1;3354:28:3;;-1:-1:-1;;3354:28:3;3244:184;3422:5;3421:6;;3406;:22;;3399:29;;;;;;;", "source": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity ^0.7.0;\n\n/// @title Math library - Allows calculation of logarithmic and exponential functions\n/// @author Alan Lu - <alan.lu@gnosis.pm>\n/// @author Stefan George - <stefan@gnosis.pm>\nlibrary GnosisMath {\n /*\n * Constants\n */\n // This is equal to 1 in our calculations\n uint public constant ONE = 0x10000000000000000;\n uint public constant LN2 = 0xb17217f7d1cf79ac;\n uint public constant LOG2_E = 0x171547652b82fe177;\n\n /*\n * Public functions\n */\n /// @dev Returns natural exponential function value of given x\n /// @param x x\n /// @return e**x\n function exp(int x) public pure returns (uint) {\n // revert if x is > MAX_POWER, where\n // MAX_POWER = int(mp.floor(mp.log(mpf(2**256 - 1) / ONE) * ONE))\n require(x <= 2454971259878909886679);\n // return 0 if exp(x) is tiny, using\n // MIN_POWER = int(mp.floor(mp.log(mpf(1) / ONE) * ONE))\n if (x < -818323753292969962227) return 0;\n // Transform so that e^x -> 2^x\n x = x * int(ONE) / int(LN2);\n // 2^x = 2^whole(x) * 2^frac(x)\n // ^^^^^^^^^^ is a bit shift\n // so Taylor expand on z = frac(x)\n int shift;\n uint z;\n if (x >= 0) {\n shift = x / int(ONE);\n z = uint(x % int(ONE));\n } else {\n shift = x / int(ONE) - 1;\n z = ONE - uint(-x % int(ONE));\n }\n // 2^x = 1 + (ln 2) x + (ln 2)^2/2! x^2 + ...\n //\n // Can generate the z coefficients using mpmath and the following lines\n // >>> from mpmath import mp\n // >>> mp.dps = 100\n // >>> ONE = 0x10000000000000000\n // >>> print('\\n'.join(hex(int(mp.log(2)**i / mp.factorial(i) * ONE)) for i in range(1, 7)))\n // 0xb17217f7d1cf79ab\n // 0x3d7f7bff058b1d50\n // 0xe35846b82505fc5\n // 0x276556df749cee5\n // 0x5761ff9e299cc4\n // 0xa184897c363c3\n uint zpow = z;\n uint result = ONE;\n result += 0xb17217f7d1cf79ab * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0x3d7f7bff058b1d50 * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0xe35846b82505fc5 * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0x276556df749cee5 * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0x5761ff9e299cc4 * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0xa184897c363c3 * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0xffe5fe2c4586 * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0x162c0223a5c8 * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0x1b5253d395e * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0x1e4cf5158b * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0x1e8cac735 * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0x1c3bd650 * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0x1816193 * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0x131496 * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0xe1b7 * zpow / ONE;\n zpow = zpow * z / ONE;\n result += 0x9c7 * zpow / ONE;\n if (shift >= 0) {\n if (result >> (uint(256) - uint(shift)) > 0) return (2 ** 256 - 1);\n return result << uint(shift);\n } else return result >> uint(-shift);\n }\n\n /// @dev Returns natural logarithm value of given x\n /// @param x x\n /// @return ln(x)\n function ln(uint x) public pure returns (int) {\n require(x > 0);\n // binary search for floor(log2(x))\n int ilog2 = floorLog2(x);\n int z;\n if (ilog2 < 0) z = int(x << uint(-ilog2));\n else z = int(x >> uint(ilog2));\n // z = x * 2^-⌊log₂x⌋\n // so 1 <= z < 2\n // and ln z = ln x - ⌊log₂x⌋/log₂e\n // so just compute ln z using artanh series\n // and calculate ln x from that\n int term = (z - int(ONE)) * int(ONE) / (z + int(ONE));\n int halflnz = term;\n int termpow = term * term / int(ONE) * term / int(ONE);\n halflnz += termpow / 3;\n termpow = termpow * term / int(ONE) * term / int(ONE);\n halflnz += termpow / 5;\n termpow = termpow * term / int(ONE) * term / int(ONE);\n halflnz += termpow / 7;\n termpow = termpow * term / int(ONE) * term / int(ONE);\n halflnz += termpow / 9;\n termpow = termpow * term / int(ONE) * term / int(ONE);\n halflnz += termpow / 11;\n termpow = termpow * term / int(ONE) * term / int(ONE);\n halflnz += termpow / 13;\n termpow = termpow * term / int(ONE) * term / int(ONE);\n halflnz += termpow / 15;\n termpow = termpow * term / int(ONE) * term / int(ONE);\n halflnz += termpow / 17;\n termpow = termpow * term / int(ONE) * term / int(ONE);\n halflnz += termpow / 19;\n termpow = termpow * term / int(ONE) * term / int(ONE);\n halflnz += termpow / 21;\n termpow = termpow * term / int(ONE) * term / int(ONE);\n halflnz += termpow / 23;\n termpow = termpow * term / int(ONE) * term / int(ONE);\n halflnz += termpow / 25;\n return (ilog2 * int(ONE)) * int(ONE) / int(LOG2_E) + 2 * halflnz;\n }\n\n /// @dev Returns base 2 logarithm value of given x\n /// @param x x\n /// @return lo - logarithmic value\n function floorLog2(uint x) public pure returns (int lo) {\n lo = -64;\n int hi = 193;\n // I use a shift here instead of / 2 because it floors instead of rounding towards 0\n int mid = (hi + lo) >> 1;\n while ((lo + 1) < hi) {\n if (mid < 0 && x << uint(-mid) < ONE || mid >= 0 && x >> uint(mid) < ONE) hi = mid;\n else lo = mid;\n mid = (hi + lo) >> 1;\n }\n }\n\n /// @dev Returns maximum of an array\n /// @param nums Numbers to look through\n /// @return maxNum - Maximum number\n function max(int[] memory nums) public pure returns (int maxNum) {\n require(nums.length > 0);\n maxNum = -2 ** 255;\n for (uint i = 0; i < nums.length; i++) if (nums[i] > maxNum) maxNum = nums[i];\n }\n\n /// @dev Returns whether an add operation causes an overflow\n /// @param a First addend\n /// @param b Second addend\n /// @return Did no overflow occur?\n function safeToAdd(uint a, uint b) internal pure returns (bool) {\n return a + b >= a;\n }\n\n /// @dev Returns whether a subtraction operation causes an underflow\n /// @param a Minuend\n /// @param b Subtrahend\n /// @return Did no underflow occur?\n function safeToSub(uint a, uint b) internal pure returns (bool) {\n return a >= b;\n }\n\n /// @dev Returns whether a multiply operation causes an overflow\n /// @param a First factor\n /// @param b Second factor\n /// @return Did no overflow occur?\n function safeToMul(uint a, uint b) internal pure returns (bool) {\n return b == 0 || a * b / b == a;\n }\n\n /// @dev Returns sum if no overflow occurred\n /// @param a First addend\n /// @param b Second addend\n /// @return Sum\n function add(uint a, uint b) internal pure returns (uint) {\n require(safeToAdd(a, b));\n return a + b;\n }\n\n /// @dev Returns difference if no overflow occurred\n /// @param a Minuend\n /// @param b Subtrahend\n /// @return Difference\n function sub(uint a, uint b) internal pure returns (uint) {\n require(safeToSub(a, b));\n return a - b;\n }\n\n /// @dev Returns product if no overflow occurred\n /// @param a First factor\n /// @param b Second factor\n /// @return Product\n function mul(uint a, uint b) internal pure returns (uint) {\n require(safeToMul(a, b));\n return a * b;\n }\n\n /// @dev Returns whether an add operation causes an overflow\n /// @param a First addend\n /// @param b Second addend\n /// @return Did no overflow occur?\n function safeToAdd(int a, int b) internal pure returns (bool) {\n return (b >= 0 && a + b >= a) || (b < 0 && a + b < a);\n }\n\n /// @dev Returns whether a subtraction operation causes an underflow\n /// @param a Minuend\n /// @param b Subtrahend\n /// @return Did no underflow occur?\n function safeToSub(int a, int b) internal pure returns (bool) {\n return (b >= 0 && a - b <= a) || (b < 0 && a - b > a);\n }\n\n /// @dev Returns whether a multiply operation causes an overflow\n /// @param a First factor\n /// @param b Second factor\n /// @return Did no overflow occur?\n function safeToMul(int a, int b) internal pure returns (bool) {\n return (b == 0) || (a * b / b == a);\n }\n\n /// @dev Returns sum if no overflow occurred\n /// @param a First addend\n /// @param b Second addend\n /// @return Sum\n function add(int a, int b) internal pure returns (int) {\n require(safeToAdd(a, b));\n return a + b;\n }\n\n /// @dev Returns difference if no overflow occurred\n /// @param a Minuend\n /// @param b Subtrahend\n /// @return Difference\n function sub(int a, int b) internal pure returns (int) {\n require(safeToSub(a, b));\n return a - b;\n }\n\n /// @dev Returns product if no overflow occurred\n /// @param a First factor\n /// @param b Second factor\n /// @return Product\n function mul(int a, int b) internal pure returns (int) {\n require(safeToMul(a, b));\n return a * b;\n }\n}\n", "sourcePath": "/Users/bensniff/Projects/gnosis/util-contracts/contracts/Math.sol", "ast": { "absolutePath": "/Users/bensniff/Projects/gnosis/util-contracts/contracts/Math.sol", "exportedSymbols": { "GnosisMath": [ 1553 ] }, "id": 1554, "license": "LGPL-3.0-only", "nodeType": "SourceUnit", "nodes": [ { "id": 354, "literals": [ "solidity", "^", "0.7", ".0" ], "nodeType": "PragmaDirective", "src": "42:23:3" }, { "abstract": false, "baseContracts": [], "contractDependencies": [], "contractKind": "library", "documentation": { "id": 355, "nodeType": "StructuredDocumentation", "src": "67:175:3", "text": "@title Math library - Allows calculation of logarithmic and exponential functions\n @author Alan Lu - <alan.lu@gnosis.pm>\n @author Stefan George - <stefan@gnosis.pm>" }, "fullyImplemented": true, "id": 1553, "linearizedBaseContracts": [ 1553 ], "name": "GnosisMath", "nodeType": "ContractDefinition", "nodes": [ { "constant": true, "functionSelector": "c2ee3a08", "id": 358, "mutability": "constant", "name": "ONE", "nodeType": "VariableDeclaration", "scope": 1553, "src": "346:46:3", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, "typeName": { "id": 356, "name": "uint", "nodeType": "ElementaryTypeName", "src": "346:4:3", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "value": { "hexValue": "30783130303030303030303030303030303030", "id": 357, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "373:19:3", "typeDescriptions": { "typeIdentifier": "t_rational_18446744073709551616_by_1", "typeString": "int_const 18446744073709551616" }, "value": "0x10000000000000000" }, "visibility": "public" }, { "constant": true, "functionSelector": "02780677", "id": 361, "mutability": "constant", "name": "LN2", "nodeType": "VariableDeclaration", "scope": 1553, "src": "398:45:3", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, "typeName": { "id": 359, "name": "uint", "nodeType": "ElementaryTypeName", "src": "398:4:3", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "value": { "hexValue": "307862313732313766376431636637396163", "id": 360, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "425:18:3", "typeDescriptions": { "typeIdentifier": "t_rational_12786308645202655660_by_1", "typeString": "int_const 12786308645202655660" }, "value": "0xb17217f7d1cf79ac" }, "visibility": "public" }, { "constant": true, "functionSelector": "24902e24", "id": 364, "mutability": "constant", "name": "LOG2_E", "nodeType": "VariableDeclaration", "scope": 1553, "src": "449:49:3", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, "typeName": { "id": 362, "name": "uint", "nodeType": "ElementaryTypeName", "src": "449:4:3", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "value": { "hexValue": "30783137313534373635326238326665313737", "id": 363, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "479:19:3", "typeDescriptions": { "typeIdentifier": "t_rational_26613026195688644983_by_1", "typeString": "int_const 26613026195688644983" }, "value": "0x171547652b82fe177" }, "visibility": "public" }, { "body": { "id": 756, "nodeType": "Block", "src": "699:2736:3", "statements": [ { "expression": { "arguments": [ { "commonType": { "typeIdentifier": "t_int256", "typeString": "int256" }, "id": 375, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, "leftExpression": { "id": 373, "name": "x", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 367, "src": "836:1:3", "typeDescriptions": { "typeIdentifier": "t_int256", "typeString": "int256" } }, "nodeType": "BinaryOperation", "operator": "<=", "rightExpression": { "hexValue": "32343534393731323539383738393039383836363739", "id": 374, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "841:22:3", "typeDescriptions": { "typeIdentifier": "t_rational_2454971259878909886679_by_1", "typeString": "int_const 2454971259878909886679" }, "value": "2454971259878909886679" }, "src": "836:27:3", "typeDescriptions": { "typeIdentifier": "t_bool", "typeString": "bool" } } ], "expression": { "argumentTypes": [ { "typeIdentifier": "t_bool", "typeString": "bool" } ], "id": 372, "name": "require", "nodeType": "Identifier", "overloadedDeclarations": [ -18, -18 ], "referencedDeclaration": -18, "src": "828:7:3", "typeDescriptions": { "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", "typeString": "function (bool) pure" } }, "id": 376, "isConstant": false, "isLValue": false, "isPure": false, "kind": "functionCall", "lValueRequested": false, "names": [], "nodeType": "FunctionCall", "src": "828:36:3", "tryCall": false, "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } }, "id": 377, "nodeType": "ExpressionStatement", "src": "828:36:3" }, { "condition": { "commonType": { "typeIdentifier": "t_int256", "typeString": "int256" }, "id": 381, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, "leftExpression": { "id": 378, "name": "x", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 367, "src": "988:1:3", "typeDescriptions": { "typeIdentifier": "t_int256", "typeString": "int256" } }, "nodeType": "BinaryOperation", "operator": "<", "rightExpression": { "id": 380, "isConstant": false, "isLValue": false, "isPure": true, "lValueRequested": false, "nodeType": "UnaryOperation", "operator": "-", "prefix": true, "src": "992:22:3", "subExpression": { "hexValue": "383138333233373533323932393639393632323237", "id": 379, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "993:21:3", "typeDescriptions": { "typeIdentifier": "t_rational_818323753292969962227_by_1", "typeString": "int_const 818323753292969962227" }, "value": "818323753292969962227" }, "typeDescriptions": { "typeIdentifier": "t_rational_minus_818323753292969962227_by_1", "typeString": "int_const -818323753292969962227" } }, "src": "988:26:3", "typeDescriptions": { "typeIdentifier": "t_bool", "typeString": "bool" } }, "id": 384, "nodeType": "IfStatement", "src": "984:40:3", "trueBody": { "expression": { "hexValue": "30", "id": 382, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "1023:1:3", "typeDescriptions": { "typeIdentifier": "t_rational_0_by_1", "typeString": "int_const 0" }, "value": "0" }, "functionReturnParameters": 371, "id": 383, "nodeType": "Return", "src": "1016:8:3" } }, { "expression": { "id": 397, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, "leftHandSide": { "id": 385, "name": "x", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 367, "src": "1074:1:3", "typeDescriptions": { "typeIdentifier": "t_int256", "typeString": "int256" } }, "nodeType": "Assignment", "operator": "=", "rightHandSide": { "commonType": { "typeIdentifier": "t_int256", "typeString": "int256" }, "id": 396, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, "leftExpression": { "commonType": { "typeIdentifier": "t_int256", "typeString": "int256" }, "id": 391, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, "leftExpression": { "id": 386, "name": "x", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 367, "src": "1078:1:3", "typeDescriptions": { "typeIdentifier": "t_int256", "typeString": "int256" } }, "nodeType": "BinaryOperation", "operator": "*", "rightExpression": { "arguments": [ { "id": 389, "name": "ONE", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 358, "src": "1086:3:3", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } } ], "expression": { "argumentTypes": [ { "typeIdentifier": "t_uint256", "typeString": "uint256" } ], "id": 388, "isConstant": false, "isLValue": false, "isPure": true, "lValueRequested": false, "nodeType": "ElementaryTypeNameExpression", "src": "1082:3:3", "typeDescriptions": { "typeIdentifier": "t_type$_t_int256_$", "typeString": "type(int256)" }, "typeName": { "id": 387, "name": "int", "nodeType": "ElementaryTypeName", "src": "1082:3:3", "typeDescriptions": {} } }, "id": 390, "isConstant": false, "isLValue": false, "isPure": true, "kind": "typeConversion", "lValueRequested": false, "names": [], "nodeType": "FunctionCall", "src": "1082:8:3", "tryCall": false, "typeDescriptions": { "typeIdentifier": "t_int256", "typeString": "int256" } }, "src": "1078:12:3", "typeDescriptions": { "typeIdentifier": "t_int256", "typeString": "int256" } }, "nodeType": "BinaryOperation", "operator": "/", "rightExpression": { "arguments": [ { "id": 394, "name": "LN2", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 361, "src": "1097:3:3", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } } ], "expression": { "argumentTypes": [ { "typeIdentifier": "t_uint256", "typeString": "uint256" } ], "id": 393, "isConstant": false, "isLValue": false, "isPure": true, "lValueRequested": false, "nodeType": "ElementaryTypeNameExpression", "src": "1093:3:3", "typeDescriptions": { "typeIdentifier": "t_type$_t_int256_$", "typeString": "type(int256)" }, "typeName": { "id": 392, "name": "int", "nodeType": "ElementaryTypeName", "src": "1093:3:3", "typeDescriptions": {} } }, "id": 395, "isConstant": false, "isLValue": false, "isPure": true, "kind": "typeConversion", "lValueRequested": false, "names": [], "nodeType": "FunctionCall", "src": "1093:8:3", "tryCall": false, "typeDescriptions": { "typeIdentifier": "t_int256", "typeString": "int256" } }, "src": "1078:23:3", "typeDescriptions": { "typeIdentifier": "t_int256", "typeString": "int256" } }, "src": "1074:27:3", "typeDescriptions": { "typeIdentifier": "t_int256", "typeString": "int256" } }, "id": 398, "nodeType": "ExpressionStatement", "src": "1074:27:3" }, { "assignments": [ 400 ], "declarations": [ { "constant": false, "id": 400, "mutability": "mutable", "name": "shift", "nodeType": "VariableDeclaration", "scope": 756, "src": "1237:9:3", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_int256", "typeString": "int256" }, "typeName": {