pragma solidity ^0.6.0; import { IERC20 } from "github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; library CTHelpers { /// @dev Constructs a condition ID from an oracle, a question ID, and the outcome slot count for the question. /// @param oracle The account assigned to report the result for the prepared condition. /// @param questionId An identifier for the question to be answered by the oracle. /// @param outcomeSlotCount The number of outcome slots which should be used for this condition. Must not exceed 256. function getConditionId(address oracle, bytes32 questionId, uint outcomeSlotCount) internal pure returns (bytes32) { return keccak256(abi.encodePacked(oracle, questionId, outcomeSlotCount)); } uint constant P = 21888242871839275222246405745257275088696311157297823662689037894645226208583; uint constant B = 3; function sqrt(uint x) private pure returns (uint y) { uint p = P; // solium-disable-next-line security/no-inline-assembly assembly { // add chain generated via https://crypto.stackexchange.com/q/27179/71252 // and transformed to the following program: // x=1; y=x+x; z=y+y; z=z+z; y=y+z; x=x+y; y=y+x; z=y+y; t=z+z; t=z+t; t=t+t; // t=t+t; z=z+t; x=x+z; z=x+x; z=z+z; y=y+z; z=y+y; z=z+z; z=z+z; z=y+z; x=x+z; // z=x+x; z=z+z; z=z+z; z=x+z; y=y+z; x=x+y; z=x+x; z=z+z; y=y+z; z=y+y; t=z+z; // t=t+t; t=t+t; z=z+t; x=x+z; y=y+x; z=y+y; z=z+z; z=z+z; x=x+z; z=x+x; z=z+z; // z=x+z; z=z+z; z=z+z; z=x+z; y=y+z; z=y+y; t=z+z; t=t+t; t=z+t; t=y+t; t=t+t; // t=t+t; t=t+t; t=t+t; z=z+t; x=x+z; z=x+x; z=x+z; y=y+z; z=y+y; z=y+z; z=z+z; // t=z+z; t=z+t; w=t+t; w=w+w; w=w+w; w=w+w; w=w+w; t=t+w; z=z+t; x=x+z; y=y+x; // z=y+y; x=x+z; y=y+x; x=x+y; y=y+x; x=x+y; z=x+x; z=x+z; z=z+z; y=y+z; z=y+y; // z=z+z; x=x+z; y=y+x; z=y+y; z=y+z; x=x+z; y=y+x; x=x+y; y=y+x; z=y+y; z=z+z; // z=y+z; x=x+z; z=x+x; z=x+z; y=y+z; x=x+y; y=y+x; x=x+y; y=y+x; z=y+y; z=y+z; // z=z+z; x=x+z; y=y+x; z=y+y; z=y+z; z=z+z; x=x+z; z=x+x; t=z+z; t=t+t; t=z+t; // t=x+t; t=t+t; t=t+t; t=t+t; t=t+t; z=z+t; y=y+z; x=x+y; y=y+x; x=x+y; z=x+x; // z=x+z; z=z+z; z=z+z; z=z+z; z=x+z; y=y+z; z=y+y; z=y+z; z=z+z; x=x+z; z=x+x; // z=x+z; y=y+z; x=x+y; z=x+x; z=z+z; y=y+z; x=x+y; z=x+x; y=y+z; x=x+y; y=y+x; // z=y+y; z=y+z; x=x+z; y=y+x; z=y+y; z=y+z; z=z+z; z=z+z; x=x+z; z=x+x; z=z+z; // z=z+z; z=x+z; y=y+z; x=x+y; z=x+x; t=x+z; t=t+t; t=t+t; z=z+t; y=y+z; z=y+y; // x=x+z; y=y+x; x=x+y; y=y+x; x=x+y; y=y+x; z=y+y; t=y+z; z=y+t; z=z+z; z=z+z; // z=t+z; x=x+z; y=y+x; x=x+y; y=y+x; x=x+y; z=x+x; z=x+z; y=y+z; x=x+y; x=x+x; // x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; // x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; // x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; // x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; // x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; // x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; // x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; // x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; // x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; // x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; // x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; x=x+x; // x=x+x; x=x+x; x=x+x; x=x+x; res=y+x // res == (P + 1) // 4 y := mulmod(x, x, p) { let z := mulmod(y, y, p) z := mulmod(z, z, p) y := mulmod(y, z, p) x := mulmod(x, y, p) y := mulmod(y, x, p) z := mulmod(y, y, p) { let t := mulmod(z, z, p) t := mulmod(z, t, p) t := mulmod(t, t, p) t := mulmod(t, t, p) z := mulmod(z, t, p) x := mulmod(x, z, p) z := mulmod(x, x, p) z := mulmod(z, z, p) y := mulmod(y, z, p) z := mulmod(y, y, p) z := mulmod(z, z, p) z := mulmod(z, z, p) z := mulmod(y, z, p) x := mulmod(x, z, p) z := mulmod(x, x, p) z := mulmod(z, z, p) z := mulmod(z, z, p) z := mulmod(x, z, p) y := mulmod(y, z, p) x := mulmod(x, y, p) z := mulmod(x, x, p) z := mulmod(z, z, p) y := mulmod(y, z, p) z := mulmod(y, y, p) t := mulmod(z, z, p) t := mulmod(t, t, p) t := mulmod(t, t, p) z := mulmod(z, t, p) x := mulmod(x, z, p) y := mulmod(y, x, p) z := mulmod(y, y, p) z := mulmod(z, z, p) z := mulmod(z, z, p) x := mulmod(x, z, p) z := mulmod(x, x, p) z := mulmod(z, z, p) z := mulmod(x, z, p) z := mulmod(z, z, p) z := mulmod(z, z, p) z := mulmod(x, z, p) y := mulmod(y, z, p) z := mulmod(y, y, p) t := mulmod(z, z, p) t := mulmod(t, t, p) t := mulmod(z, t, p) t := mulmod(y, t, p) t := mulmod(t, t, p) t := mulmod(t, t, p) t := mulmod(t, t, p) t := mulmod(t, t, p) z := mulmod(z, t, p) x := mulmod(x, z, p) z := mulmod(x, x, p) z := mulmod(x, z, p) y := mulmod(y, z, p) z := mulmod(y, y, p) z := mulmod(y, z, p) z := mulmod(z, z, p) t := mulmod(z, z, p) t := mulmod(z, t, p) { let w := mulmod(t, t, p) w := mulmod(w, w, p) w := mulmod(w, w, p) w := mulmod(w, w, p) w := mulmod(w, w, p) t := mulmod(t, w, p) } z := mulmod(z, t, p) x := mulmod(x, z, p) y := mulmod(y, x, p) z := mulmod(y, y, p) x := mulmod(x, z, p) y := mulmod(y, x, p) x := mulmod(x, y, p) y := mulmod(y, x, p) x := mulmod(x, y, p) z := mulmod(x, x, p) z := mulmod(x, z, p) z := mulmod(z, z, p) y := mulmod(y, z, p) z := mulmod(y, y, p) z := mulmod(z, z, p) x := mulmod(x, z, p) y := mulmod(y, x, p) z := mulmod(y, y, p) z := mulmod(y, z, p) x := mulmod(x, z, p) y := mulmod(y, x, p) x := mulmod(x, y, p) y := mulmod(y, x, p) z := mulmod(y, y, p) z := mulmod(z, z, p) z := mulmod(y, z, p) x := mulmod(x, z, p) z := mulmod(x, x, p) z := mulmod(x, z, p) y := mulmod(y, z, p) x := mulmod(x, y, p) y := mulmod(y, x, p) x := mulmod(x, y, p) y := mulmod(y, x, p) z := mulmod(y, y, p) z := mulmod(y, z, p) z := mulmod(z, z, p) x := mulmod(x, z, p) y := mulmod(y, x, p) z := mulmod(y, y, p) z := mulmod(y, z, p) z := mulmod(z, z, p) x := mulmod(x, z, p) z := mulmod(x, x, p) t := mulmod(z, z, p) t := mulmod(t, t, p) t := mulmod(z, t, p) t := mulmod(x, t, p) t := mulmod(t, t, p) t := mulmod(t, t, p) t := mulmod(t, t, p) t := mulmod(t, t, p) z := mulmod(z, t, p) y := mulmod(y, z, p) x := mulmod(x, y, p) y := mulmod(y, x, p) x := mulmod(x, y, p) z := mulmod(x, x, p) z := mulmod(x, z, p) z := mulmod(z, z, p) z := mulmod(z, z, p) z := mulmod(z, z, p) z := mulmod(x, z, p) y := mulmod(y, z, p) z := mulmod(y, y, p) z := mulmod(y, z, p) z := mulmod(z, z, p) x := mulmod(x, z, p) z := mulmod(x, x, p) z := mulmod(x, z, p) y := mulmod(y, z, p) x := mulmod(x, y, p) z := mulmod(x, x, p) z := mulmod(z, z, p) y := mulmod(y, z, p) x := mulmod(x, y, p) z := mulmod(x, x, p) y := mulmod(y, z, p) x := mulmod(x, y, p) y := mulmod(y, x, p) z := mulmod(y, y, p) z := mulmod(y, z, p) x := mulmod(x, z, p) y := mulmod(y, x, p) z := mulmod(y, y, p) z := mulmod(y, z, p) z := mulmod(z, z, p) z := mulmod(z, z, p) x := mulmod(x, z, p) z := mulmod(x, x, p) z := mulmod(z, z, p) z := mulmod(z, z, p) z := mulmod(x, z, p) y := mulmod(y, z, p) x := mulmod(x, y, p) z := mulmod(x, x, p) t := mulmod(x, z, p) t := mulmod(t, t, p) t := mulmod(t, t, p) z := mulmod(z, t, p) y := mulmod(y, z, p) z := mulmod(y, y, p) x := mulmod(x, z, p) y := mulmod(y, x, p) x := mulmod(x, y, p) y := mulmod(y, x, p) x := mulmod(x, y, p) y := mulmod(y, x, p) z := mulmod(y, y, p) t := mulmod(y, z, p) z := mulmod(y, t, p) z := mulmod(z, z, p) z := mulmod(z, z, p) z := mulmod(t, z, p) } x := mulmod(x, z, p) y := mulmod(y, x, p) x := mulmod(x, y, p) y := mulmod(y, x, p) x := mulmod(x, y, p) z := mulmod(x, x, p) z := mulmod(x, z, p) y := mulmod(y, z, p) } x := mulmod(x, y, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) x := mulmod(x, x, p) y := mulmod(y, x, p) } } /// @dev Constructs an outcome collection ID from a parent collection and an outcome collection. /// @param parentCollectionId Collection ID of the parent outcome collection, or bytes32(0) if there's no parent. /// @param conditionId Condition ID of the outcome collection to combine with the parent outcome collection. /// @param indexSet Index set of the outcome collection to combine with the parent outcome collection. function getCollectionId(bytes32 parentCollectionId, bytes32 conditionId, uint indexSet) internal view returns (bytes32) { uint x1 = uint(keccak256(abi.encodePacked(conditionId, indexSet))); bool odd = x1 >> 255 != 0; uint y1; uint yy; do { x1 = addmod(x1, 1, P); yy = addmod(mulmod(x1, mulmod(x1, x1, P), P), B, P); y1 = sqrt(yy); } while(mulmod(y1, y1, P) != yy); if(odd && y1 % 2 == 0 || !odd && y1 % 2 == 1) y1 = P - y1; uint x2 = uint(parentCollectionId); if(x2 != 0) { odd = x2 >> 254 != 0; x2 = (x2 << 2) >> 2; yy = addmod(mulmod(x2, mulmod(x2, x2, P), P), B, P); uint y2 = sqrt(yy); if(odd && y2 % 2 == 0 || !odd && y2 % 2 == 1) y2 = P - y2; require(mulmod(y2, y2, P) == yy, "invalid parent collection ID"); (bool success, bytes memory ret) = address(6).staticcall(abi.encode(x1, y1, x2, y2)); require(success, "ecadd failed"); (x1, y1) = abi.decode(ret, (uint, uint)); } if(y1 % 2 == 1) x1 ^= 1 << 254; return bytes32(x1); } /// @dev Constructs a position ID from a collateral token and an outcome collection. These IDs are used as the ERC-1155 ID for this contract. /// @param collateralToken Collateral token which backs the position. /// @param collectionId ID of the outcome collection associated with this position. function getPositionId(IERC20 collateralToken, bytes32 collectionId) internal pure returns (uint) { return uint(keccak256(abi.encodePacked(collateralToken, collectionId))); } }