文件 1 的 1:AugurWalletRegistry.sol
pragma solidity 0.5.15;
contract IAugur {
function createChildUniverse(bytes32 _parentPayoutDistributionHash, uint256[] memory _parentPayoutNumerators) public returns (IUniverse);
function isKnownUniverse(IUniverse _universe) public view returns (bool);
function trustedCashTransfer(address _from, address _to, uint256 _amount) public returns (bool);
function isTrustedSender(address _address) public returns (bool);
function onCategoricalMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, bytes32[] memory _outcomes) public returns (bool);
function onYesNoMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash) public returns (bool);
function onScalarMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, int256[] memory _prices, uint256 _numTicks) public returns (bool);
function logInitialReportSubmitted(IUniverse _universe, address _reporter, address _market, address _initialReporter, uint256 _amountStaked, bool _isDesignatedReporter, uint256[] memory _payoutNumerators, string memory _description, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime) public returns (bool);
function disputeCrowdsourcerCreated(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _size, uint256 _disputeRound) public returns (bool);
function logDisputeCrowdsourcerContribution(IUniverse _universe, address _reporter, address _market, address _disputeCrowdsourcer, uint256 _amountStaked, string memory description, uint256[] memory _payoutNumerators, uint256 _currentStake, uint256 _stakeRemaining, uint256 _disputeRound) public returns (bool);
function logDisputeCrowdsourcerCompleted(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime, bool _pacingOn, uint256 _totalRepStakedInPayout, uint256 _totalRepStakedInMarket, uint256 _disputeRound) public returns (bool);
function logInitialReporterRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool);
function logDisputeCrowdsourcerRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool);
function logMarketFinalized(IUniverse _universe, uint256[] memory _winningPayoutNumerators) public returns (bool);
function logMarketMigrated(IMarket _market, IUniverse _originalUniverse) public returns (bool);
function logReportingParticipantDisavowed(IUniverse _universe, IMarket _market) public returns (bool);
function logMarketParticipantsDisavowed(IUniverse _universe) public returns (bool);
function logCompleteSetsPurchased(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool);
function logCompleteSetsSold(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets, uint256 _fees) public returns (bool);
function logMarketOIChanged(IUniverse _universe, IMarket _market) public returns (bool);
function logTradingProceedsClaimed(IUniverse _universe, address _sender, address _market, uint256 _outcome, uint256 _numShares, uint256 _numPayoutTokens, uint256 _fees) public returns (bool);
function logUniverseForked(IMarket _forkingMarket) public returns (bool);
function logReputationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
function logReputationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
function logReputationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
function logShareTokensBalanceChanged(address _account, IMarket _market, uint256 _outcome, uint256 _balance) public returns (bool);
function logDisputeCrowdsourcerTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
function logDisputeCrowdsourcerTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
function logDisputeCrowdsourcerTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
function logDisputeWindowCreated(IDisputeWindow _disputeWindow, uint256 _id, bool _initial) public returns (bool);
function logParticipationTokensRedeemed(IUniverse universe, address _sender, uint256 _attoParticipationTokens, uint256 _feePayoutShare) public returns (bool);
function logTimestampSet(uint256 _newTimestamp) public returns (bool);
function logInitialReporterTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool);
function logMarketTransferred(IUniverse _universe, address _from, address _to) public returns (bool);
function logParticipationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
function logParticipationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
function logParticipationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
function logMarketRepBondTransferred(address _universe, address _from, address _to) public returns (bool);
function logWarpSyncDataUpdated(address _universe, uint256 _warpSyncHash, uint256 _marketEndTime) public returns (bool);
function isKnownFeeSender(address _feeSender) public view returns (bool);
function lookup(bytes32 _key) public view returns (address);
function getTimestamp() public view returns (uint256);
function getMaximumMarketEndDate() public returns (uint256);
function isKnownMarket(IMarket _market) public view returns (bool);
function derivePayoutDistributionHash(uint256[] memory _payoutNumerators, uint256 _numTicks, uint256 numOutcomes) public view returns (bytes32);
function logValidityBondChanged(uint256 _validityBond) public returns (bool);
function logDesignatedReportStakeChanged(uint256 _designatedReportStake) public returns (bool);
function logNoShowBondChanged(uint256 _noShowBond) public returns (bool);
function logReportingFeeChanged(uint256 _reportingFee) public returns (bool);
function getUniverseForkIndex(IUniverse _universe) public view returns (uint256);
}
interface IAugurWallet {
function initialize(address _owner, address _referralAddress, bytes32 _fingerprint, address _augur, address _registry, address _registryV2, IERC20 _cash, IAffiliates _affiliates, IERC1155 _shareToken, address _createOrder, address _fillOrder, address _zeroXTrade) external;
function transferCash(address _to, uint256 _amount) external;
function executeTransaction(address _to, bytes calldata _data, uint256 _value) external returns (bool);
}
interface IAugurWalletRegistry {
function ethExchange() external returns (IUniswapV2Pair);
function WETH() external returns (IWETH);
function token0IsCash() external returns (bool);
}
contract IAugurWalletFactory {
function getCreate2WalletAddress(address _owner) external view returns (address);
function createAugurWallet(address _owner, address _referralAddress, bytes32 _fingerprint) public returns (IAugurWallet);
}
contract Context {
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this;
return msg.data;
}
}
interface IRelayHub {
function stake(address relayaddr, uint256 unstakeDelay) external payable;
event Staked(address indexed relay, uint256 stake, uint256 unstakeDelay);
function registerRelay(uint256 transactionFee, string calldata url) external;
event RelayAdded(address indexed relay, address indexed owner, uint256 transactionFee, uint256 stake, uint256 unstakeDelay, string url);
function removeRelayByOwner(address relay) external;
event RelayRemoved(address indexed relay, uint256 unstakeTime);
function unstake(address relay) external;
event Unstaked(address indexed relay, uint256 stake);
enum RelayState {
Unknown,
Staked,
Registered,
Removed
}
function getRelay(address relay) external view returns (uint256 totalStake, uint256 unstakeDelay, uint256 unstakeTime, address payable owner, RelayState state);
function depositFor(address target) external payable;
event Deposited(address indexed recipient, address indexed from, uint256 amount);
function balanceOf(address target) external view returns (uint256);
function withdraw(uint256 amount, address payable dest) external;
event Withdrawn(address indexed account, address indexed dest, uint256 amount);
function canRelay(
address relay,
address from,
address to,
bytes calldata encodedFunction,
uint256 transactionFee,
uint256 gasPrice,
uint256 gasLimit,
uint256 nonce,
bytes calldata signature,
bytes calldata approvalData
) external view returns (uint256 status, bytes memory recipientContext);
enum PreconditionCheck {
OK,
WrongSignature,
WrongNonce,
AcceptRelayedCallReverted,
InvalidRecipientStatusCode
}
function relayCall(
address from,
address to,
bytes calldata encodedFunction,
uint256 transactionFee,
uint256 gasPrice,
uint256 gasLimit,
uint256 nonce,
bytes calldata signature,
bytes calldata approvalData
) external;
event CanRelayFailed(address indexed relay, address indexed from, address indexed to, bytes4 selector, uint256 reason);
event TransactionRelayed(address indexed relay, address indexed from, address indexed to, bytes4 selector, RelayCallStatus status, uint256 charge);
enum RelayCallStatus {
OK,
RelayedCallFailed,
PreRelayedFailed,
PostRelayedFailed,
RecipientBalanceChanged
}
function requiredGas(uint256 relayedCallStipend) external view returns (uint256);
function maxPossibleCharge(uint256 relayedCallStipend, uint256 gasPrice, uint256 transactionFee) external view returns (uint256);
function penalizeRepeatedNonce(bytes calldata unsignedTx1, bytes calldata signature1, bytes calldata unsignedTx2, bytes calldata signature2) external;
function penalizeIllegalTransaction(bytes calldata unsignedTx, bytes calldata signature) external;
event Penalized(address indexed relay, address sender, uint256 amount);
function getNonce(address from) external view returns (uint256);
}
interface IRelayRecipient {
function getHubAddr() external view returns (address);
function acceptRelayedCall(
address relay,
address from,
bytes calldata encodedFunction,
uint256 transactionFee,
uint256 gasPrice,
uint256 gasLimit,
uint256 nonce,
bytes calldata approvalData,
uint256 maxPossibleCharge
)
external
view
returns (uint256, bytes memory);
function preRelayedCall(bytes calldata context) external returns (bytes32);
function postRelayedCall(bytes calldata context, bool success, uint256 actualCharge, bytes32 preRetVal) external;
}
contract GSNRecipient is IRelayRecipient, Context {
address private _relayHub = 0xD216153c06E857cD7f72665E0aF1d7D82172F494;
uint256 constant private RELAYED_CALL_ACCEPTED = 0;
uint256 constant private RELAYED_CALL_REJECTED = 11;
uint256 constant internal POST_RELAYED_CALL_MAX_GAS = 100000;
event RelayHubChanged(address indexed oldRelayHub, address indexed newRelayHub);
function getHubAddr() public view returns (address) {
return _relayHub;
}
function _upgradeRelayHub(address newRelayHub) internal {
address currentRelayHub = _relayHub;
require(newRelayHub != address(0), "GSNRecipient: new RelayHub is the zero address");
require(newRelayHub != currentRelayHub, "GSNRecipient: new RelayHub is the current one");
emit RelayHubChanged(currentRelayHub, newRelayHub);
_relayHub = newRelayHub;
}
function relayHubVersion() public view returns (string memory) {
this;
return "1.0.0";
}
function _withdrawDeposits(uint256 amount, address payable payee) internal {
IRelayHub(_relayHub).withdraw(amount, payee);
}
function _msgSender() internal view returns (address payable) {
if (msg.sender != _relayHub) {
return msg.sender;
} else {
return _getRelayedCallSender();
}
}
function _msgData() internal view returns (bytes memory) {
if (msg.sender != _relayHub) {
return msg.data;
} else {
return _getRelayedCallData();
}
}
function preRelayedCall(bytes calldata context) external returns (bytes32) {
require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub");
return _preRelayedCall(context);
}
function _preRelayedCall(bytes memory context) internal returns (bytes32);
function postRelayedCall(bytes calldata context, bool success, uint256 actualCharge, bytes32 preRetVal) external {
require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub");
_postRelayedCall(context, success, actualCharge, preRetVal);
}
function _postRelayedCall(bytes memory context, bool success, uint256 actualCharge, bytes32 preRetVal) internal;
function _approveRelayedCall() internal pure returns (uint256, bytes memory) {
return _approveRelayedCall("");
}
function _approveRelayedCall(bytes memory context) internal pure returns (uint256, bytes memory) {
return (RELAYED_CALL_ACCEPTED, context);
}
function _rejectRelayedCall(uint256 errorCode) internal pure returns (uint256, bytes memory) {
return (RELAYED_CALL_REJECTED + errorCode, "");
}
function _computeCharge(uint256 gas, uint256 gasPrice, uint256 serviceFee) internal pure returns (uint256) {
return (gas * gasPrice * (100 + serviceFee)) / 100;
}
function _getRelayedCallSender() private pure returns (address payable result) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
result := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
return result;
}
function _getRelayedCallData() private pure returns (bytes memory) {
uint256 actualDataLength = msg.data.length - 20;
bytes memory actualData = new bytes(actualDataLength);
for (uint256 i = 0; i < actualDataLength; ++i) {
actualData[i] = msg.data[i];
}
return actualData;
}
}
library RLPReader {
uint8 constant STRING_SHORT_START = 0x80;
uint8 constant STRING_LONG_START = 0xb8;
uint8 constant LIST_SHORT_START = 0xc0;
uint8 constant LIST_LONG_START = 0xf8;
uint8 constant WORD_SIZE = 32;
struct RLPItem {
uint len;
uint memPtr;
}
using RLPReader for bytes;
using RLPReader for uint;
using RLPReader for RLPReader.RLPItem;
function decodeTransaction(bytes memory rawTransaction) internal pure returns (uint, uint, uint, address, uint, bytes memory){
RLPReader.RLPItem[] memory values = rawTransaction.toRlpItem().toList();
return (values[0].toUint(), values[1].toUint(), values[2].toUint(), values[3].toAddress(), values[4].toUint(), values[5].toBytes());
}
function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {
if (item.length == 0)
return RLPItem(0, 0);
uint memPtr;
assembly {
memPtr := add(item, 0x20)
}
return RLPItem(item.length, memPtr);
}
function toList(RLPItem memory item) internal pure returns (RLPItem[] memory result) {
require(isList(item), "isList failed");
uint items = numItems(item);
result = new RLPItem[](items);
uint memPtr = item.memPtr + _payloadOffset(item.memPtr);
uint dataLen;
for (uint i = 0; i < items; i++) {
dataLen = _itemLength(memPtr);
result[i] = RLPItem(dataLen, memPtr);
memPtr = memPtr + dataLen;
}
}
function isList(RLPItem memory item) internal pure returns (bool) {
uint8 byte0;
uint memPtr = item.memPtr;
assembly {
byte0 := byte(0, mload(memPtr))
}
if (byte0 < LIST_SHORT_START)
return false;
return true;
}
function numItems(RLPItem memory item) internal pure returns (uint) {
uint count = 0;
uint currPtr = item.memPtr + _payloadOffset(item.memPtr);
uint endPtr = item.memPtr + item.len;
while (currPtr < endPtr) {
currPtr = currPtr + _itemLength(currPtr);
count++;
}
return count;
}
function _itemLength(uint memPtr) internal pure returns (uint len) {
uint byte0;
assembly {
byte0 := byte(0, mload(memPtr))
}
if (byte0 < STRING_SHORT_START)
return 1;
else if (byte0 < STRING_LONG_START)
return byte0 - STRING_SHORT_START + 1;
else if (byte0 < LIST_SHORT_START) {
assembly {
let byteLen := sub(byte0, 0xb7)
memPtr := add(memPtr, 1)
let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen)))
len := add(dataLen, add(byteLen, 1))
}
}
else if (byte0 < LIST_LONG_START) {
return byte0 - LIST_SHORT_START + 1;
}
else {
assembly {
let byteLen := sub(byte0, 0xf7)
memPtr := add(memPtr, 1)
let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen)))
len := add(dataLen, add(byteLen, 1))
}
}
}
function _payloadOffset(uint memPtr) internal pure returns (uint) {
uint byte0;
assembly {
byte0 := byte(0, mload(memPtr))
}
if (byte0 < STRING_SHORT_START)
return 0;
else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START))
return 1;
else if (byte0 < LIST_SHORT_START)
return byte0 - (STRING_LONG_START - 1) + 1;
else
return byte0 - (LIST_LONG_START - 1) + 1;
}
function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {
bytes memory result = new bytes(item.len);
uint ptr;
assembly {
ptr := add(0x20, result)
}
copy(item.memPtr, ptr, item.len);
return result;
}
function toBoolean(RLPItem memory item) internal pure returns (bool) {
require(item.len == 1, "Invalid RLPItem. Booleans are encoded in 1 byte");
uint result;
uint memPtr = item.memPtr;
assembly {
result := byte(0, mload(memPtr))
}
return result == 0 ? false : true;
}
function toAddress(RLPItem memory item) internal pure returns (address) {
require(item.len <= 21, "Invalid RLPItem. Addresses are encoded in 20 bytes or less");
return address(toUint(item));
}
function toUint(RLPItem memory item) internal pure returns (uint) {
uint offset = _payloadOffset(item.memPtr);
uint len = item.len - offset;
uint memPtr = item.memPtr + offset;
uint result;
assembly {
result := div(mload(memPtr), exp(256, sub(32, len)))
}
return result;
}
function toBytes(RLPItem memory item) internal pure returns (bytes memory) {
uint offset = _payloadOffset(item.memPtr);
uint len = item.len - offset;
bytes memory result = new bytes(len);
uint destPtr;
assembly {
destPtr := add(0x20, result)
}
copy(item.memPtr + offset, destPtr, len);
return result;
}
function copy(uint src, uint dest, uint len) internal pure {
for (; len >= WORD_SIZE; len -= WORD_SIZE) {
assembly {
mstore(dest, mload(src))
}
src += WORD_SIZE;
dest += WORD_SIZE;
}
uint mask = 256 ** (WORD_SIZE - len) - 1;
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
}
library ContractExists {
function exists(address _address) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(_address) }
return size > 0;
}
}
contract IOwnable {
function getOwner() public view returns (address);
function transferOwnership(address _newOwner) public returns (bool);
}
contract ITyped {
function getTypeName() public view returns (bytes32);
}
contract Initializable {
bool private initialized = false;
modifier beforeInitialized {
require(!initialized);
_;
}
function endInitialization() internal beforeInitialized {
initialized = true;
}
function getInitialized() public view returns (bool) {
return initialized;
}
}
contract AugurWallet is Initializable, IAugurWallet {
using SafeMathUint256 for uint256;
IAugurWalletRegistry public registry;
mapping(address => bool) public authorizedProxies;
uint256 private constant MAX_APPROVAL_AMOUNT = 2 ** 256 - 1;
bytes32 public constant DOMAIN_SEPARATOR_TYPEHASH = 0x035aff83d86937d35b32e04f0ddc6ff469290eef2f1b692d8a815c89404d4749;
bytes32 public constant MSG_TYPEHASH = 0xe0e790a7bae5fba0106cf286392dd87dfd6ec8631e5631988133e4470b9e7b0d;
bytes4 constant internal EIP1271_MAGIC_VALUE = 0x20c13b0b;
address owner;
bytes32 public domainSeparator;
IERC20 public cash;
function initialize(address _owner, address _referralAddress, bytes32 _fingerprint, address _augur, address _registry, address _registryV2, IERC20 _cash, IAffiliates _affiliates, IERC1155 _shareToken, address _createOrder, address _fillOrder, address _zeroXTrade) external beforeInitialized {
endInitialization();
domainSeparator = keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, this));
owner = _owner;
registry = IAugurWalletRegistry(_registryV2);
authorizedProxies[_registry] = true;
authorizedProxies[_registryV2] = true;
cash = _cash;
_cash.approve(_augur, MAX_APPROVAL_AMOUNT);
_cash.approve(_createOrder, MAX_APPROVAL_AMOUNT);
_shareToken.setApprovalForAll(_createOrder, true);
_cash.approve(_fillOrder, MAX_APPROVAL_AMOUNT);
_shareToken.setApprovalForAll(_fillOrder, true);
_cash.approve(_zeroXTrade, MAX_APPROVAL_AMOUNT);
_affiliates.setFingerprint(_fingerprint);
if (_referralAddress != address(0)) {
_affiliates.setReferrer(_referralAddress);
}
}
function transferCash(address _to, uint256 _amount) external {
require(authorizedProxies[msg.sender]);
cash.transfer(_to, _amount);
}
function executeTransaction(address _to, bytes calldata _data, uint256 _value) external returns (bool) {
require(authorizedProxies[msg.sender]);
(bool _didSucceed, bytes memory _resultData) = address(_to).call.value(_value)(_data);
return _didSucceed;
}
function addAuthorizedProxy(address _authorizedProxy) external returns (bool) {
require(msg.sender == owner || authorizedProxies[msg.sender] || msg.sender == address(this));
authorizedProxies[_authorizedProxy] = true;
return true;
}
function removeAuthorizedProxy(address _authorizedProxy) external returns (bool) {
require(msg.sender == owner || authorizedProxies[msg.sender] || msg.sender == address(this));
authorizedProxies[_authorizedProxy] = false;
return true;
}
function withdrawAllFundsAsDai(address _destination, uint256 _minExchangeRateInDai) external payable returns (bool) {
require(msg.sender == owner);
IUniswapV2Pair _ethExchange = registry.ethExchange();
IWETH _weth = registry.WETH();
bool _token0IsCash = registry.token0IsCash();
uint256 _ethAmount = address(this).balance;
(uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = _ethExchange.getReserves();
uint256 _cashAmount = getAmountOut(_ethAmount, _token0IsCash ? _reserve1 : _reserve0, _token0IsCash ? _reserve0 : _reserve1);
uint256 _exchangeRate = _cashAmount.mul(10**18).div(_ethAmount);
require(_minExchangeRateInDai <= _exchangeRate, "Exchange rate too low");
_weth.deposit.value(_ethAmount)();
_weth.transfer(address(_ethExchange), _ethAmount);
_ethExchange.swap(_token0IsCash ? _cashAmount : 0, _token0IsCash ? 0 : _cashAmount, address(this), "");
cash.transfer(_destination, cash.balanceOf(address(this)));
return true;
}
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) public pure returns (uint amountOut) {
require(amountIn > 0);
require(reserveIn > 0 && reserveOut > 0);
uint amountInWithFee = amountIn.mul(997);
uint numerator = amountInWithFee.mul(reserveOut);
uint denominator = reserveIn.mul(1000).add(amountInWithFee);
amountOut = numerator / denominator;
}
function isValidSignature(bytes calldata _data, bytes calldata _signature) external view returns (bytes4) {
bytes32 _messageHash = getMessageHash(_data);
require(_signature.length >= 65, "Signature data length incorrect");
bytes32 _r;
bytes32 _s;
uint8 _v;
bytes memory _sig = _signature;
assembly {
_r := mload(add(_sig, 32))
_s := mload(add(_sig, 64))
_v := and(mload(add(_sig, 65)), 255)
}
require(owner == ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _messageHash)), _v, _r, _s), "Invalid Signature");
return EIP1271_MAGIC_VALUE;
}
function getMessageHash(bytes memory _message) public view returns (bytes32) {
bytes32 safeMessageHash = keccak256(abi.encode(MSG_TYPEHASH, keccak256(_message)));
return keccak256(abi.encodePacked(byte(0x19), byte(0x01), domainSeparator, safeMessageHash));
}
function () external payable {}
}
library LibBytes {
using LibBytes for bytes;
function equals(
bytes memory lhs,
bytes memory rhs
)
internal
pure
returns (bool equal)
{
return lhs.length == rhs.length && keccak256(lhs) == keccak256(rhs);
}
function contentAddress(bytes memory input)
internal
pure
returns (uint256 memoryAddress)
{
assembly {
memoryAddress := add(input, 32)
}
return memoryAddress;
}
function memCopy(
uint256 dest,
uint256 source,
uint256 length
)
internal
pure
{
if (length < 32) {
assembly {
let mask := sub(exp(256, sub(32, length)), 1)
let s := and(mload(source), not(mask))
let d := and(mload(dest), mask)
mstore(dest, or(s, d))
}
} else {
if (source == dest) {
return;
}
if (source > dest) {
assembly {
length := sub(length, 32)
let sEnd := add(source, length)
let dEnd := add(dest, length)
let last := mload(sEnd)
for {} lt(source, sEnd) {} {
mstore(dest, mload(source))
source := add(source, 32)
dest := add(dest, 32)
}
mstore(dEnd, last)
}
} else {
assembly {
length := sub(length, 32)
let sEnd := add(source, length)
let dEnd := add(dest, length)
let first := mload(source)
for {} slt(dest, dEnd) {} {
mstore(dEnd, mload(sEnd))
sEnd := sub(sEnd, 32)
dEnd := sub(dEnd, 32)
}
mstore(dest, first)
}
}
}
}
function slice(
bytes memory b,
uint256 from,
uint256 to
)
internal
pure
returns (bytes memory result)
{
if (from > to) {
revert();
}
if (to > b.length) {
revert();
}
result = new bytes(to - from);
memCopy(
result.contentAddress(),
b.contentAddress() + from,
result.length
);
return result;
}
function sliceDestructive(
bytes memory b,
uint256 from,
uint256 to
)
internal
pure
returns (bytes memory result)
{
if (from > to) {
revert();
}
if (to > b.length) {
revert();
}
assembly {
result := add(b, from)
mstore(result, sub(to, from))
}
return result;
}
function popLastByte(bytes memory b)
internal
pure
returns (bytes1 result)
{
if (b.length == 0) {
revert();
}
result = b[b.length - 1];
assembly {
let newLen := sub(mload(b), 1)
mstore(b, newLen)
}
return result;
}
}
library SafeMathUint256 {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a / b;
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
if (a <= b) {
return a;
} else {
return b;
}
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
if (a >= b) {
return a;
} else {
return b;
}
}
function sqrt(uint256 y) internal pure returns (uint256 z) {
if (y > 3) {
uint256 x = (y + 1) / 2;
z = y;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
}
function getUint256Min() internal pure returns (uint256) {
return 0;
}
function getUint256Max() internal pure returns (uint256) {
return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
}
function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {
return a % b == 0;
}
function fxpMul(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
return div(mul(a, b), base);
}
function fxpDiv(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
return div(mul(a, base), b);
}
}
interface IERC1155 {
event TransferSingle(
address indexed operator,
address indexed from,
address indexed to,
uint256 id,
uint256 value
);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
event URI(
string value,
uint256 indexed id
);
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 value,
bytes calldata data
)
external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
)
external;
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function balanceOf(address owner, uint256 id) external view returns (uint256);
function totalSupply(uint256 id) external view returns (uint256);
function balanceOfBatch(
address[] calldata owners,
uint256[] calldata ids
)
external
view
returns (uint256[] memory balances_);
}
contract IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address owner) public view returns (uint256);
function transfer(address to, uint256 amount) public returns (bool);
function transferFrom(address from, address to, uint256 amount) public returns (bool);
function approve(address spender, uint256 amount) public returns (bool);
function allowance(address owner, address spender) public view returns (uint256);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
contract ICash is IERC20 {
}
contract IAffiliateValidator {
function validateReference(address _account, address _referrer) external view returns (bool);
}
contract IAffiliates {
function setFingerprint(bytes32 _fingerprint) external;
function setReferrer(address _referrer) external;
function getAccountFingerprint(address _account) external returns (bytes32);
function getReferrer(address _account) external returns (address);
function getAndValidateReferrer(address _account, IAffiliateValidator affiliateValidator) external returns (address);
function affiliateValidators(address _affiliateValidator) external returns (bool);
}
contract IDisputeWindow is ITyped, IERC20 {
function invalidMarketsTotal() external view returns (uint256);
function validityBondTotal() external view returns (uint256);
function incorrectDesignatedReportTotal() external view returns (uint256);
function initialReportBondTotal() external view returns (uint256);
function designatedReportNoShowsTotal() external view returns (uint256);
function designatedReporterNoShowBondTotal() external view returns (uint256);
function initialize(IAugur _augur, IUniverse _universe, uint256 _disputeWindowId, bool _participationTokensEnabled, uint256 _duration, uint256 _startTime) public;
function trustedBuy(address _buyer, uint256 _attotokens) public returns (bool);
function getUniverse() public view returns (IUniverse);
function getReputationToken() public view returns (IReputationToken);
function getStartTime() public view returns (uint256);
function getEndTime() public view returns (uint256);
function getWindowId() public view returns (uint256);
function isActive() public view returns (bool);
function isOver() public view returns (bool);
function onMarketFinalized() public;
function redeem(address _account) public returns (bool);
}
contract IMarket is IOwnable {
enum MarketType {
YES_NO,
CATEGORICAL,
SCALAR
}
function initialize(IAugur _augur, IUniverse _universe, uint256 _endTime, uint256 _feePerCashInAttoCash, IAffiliateValidator _affiliateValidator, uint256 _affiliateFeeDivisor, address _designatedReporterAddress, address _creator, uint256 _numOutcomes, uint256 _numTicks) public;
function derivePayoutDistributionHash(uint256[] memory _payoutNumerators) public view returns (bytes32);
function doInitialReport(uint256[] memory _payoutNumerators, string memory _description, uint256 _additionalStake) public returns (bool);
function getUniverse() public view returns (IUniverse);
function getDisputeWindow() public view returns (IDisputeWindow);
function getNumberOfOutcomes() public view returns (uint256);
function getNumTicks() public view returns (uint256);
function getMarketCreatorSettlementFeeDivisor() public view returns (uint256);
function getForkingMarket() public view returns (IMarket _market);
function getEndTime() public view returns (uint256);
function getWinningPayoutDistributionHash() public view returns (bytes32);
function getWinningPayoutNumerator(uint256 _outcome) public view returns (uint256);
function getWinningReportingParticipant() public view returns (IReportingParticipant);
function getReputationToken() public view returns (IV2ReputationToken);
function getFinalizationTime() public view returns (uint256);
function getInitialReporter() public view returns (IInitialReporter);
function getDesignatedReportingEndTime() public view returns (uint256);
function getValidityBondAttoCash() public view returns (uint256);
function affiliateFeeDivisor() external view returns (uint256);
function getNumParticipants() public view returns (uint256);
function getDisputePacingOn() public view returns (bool);
function deriveMarketCreatorFeeAmount(uint256 _amount) public view returns (uint256);
function recordMarketCreatorFees(uint256 _marketCreatorFees, address _sourceAccount, bytes32 _fingerprint) public returns (bool);
function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
function isFinalizedAsInvalid() public view returns (bool);
function finalize() public returns (bool);
function isFinalized() public view returns (bool);
function getOpenInterest() public view returns (uint256);
}
contract IReportingParticipant {
function getStake() public view returns (uint256);
function getPayoutDistributionHash() public view returns (bytes32);
function liquidateLosing() public;
function redeem(address _redeemer) public returns (bool);
function isDisavowed() public view returns (bool);
function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
function getPayoutNumerators() public view returns (uint256[] memory);
function getMarket() public view returns (IMarket);
function getSize() public view returns (uint256);
}
contract IInitialReporter is IReportingParticipant, IOwnable {
function initialize(IAugur _augur, IMarket _market, address _designatedReporter) public;
function report(address _reporter, bytes32 _payoutDistributionHash, uint256[] memory _payoutNumerators, uint256 _initialReportStake) public;
function designatedReporterShowed() public view returns (bool);
function initialReporterWasCorrect() public view returns (bool);
function getDesignatedReporter() public view returns (address);
function getReportTimestamp() public view returns (uint256);
function migrateToNewUniverse(address _designatedReporter) public;
function returnRepFromDisavow() public;
}
contract IReputationToken is IERC20 {
function migrateOutByPayout(uint256[] memory _payoutNumerators, uint256 _attotokens) public returns (bool);
function migrateIn(address _reporter, uint256 _attotokens) public returns (bool);
function trustedReportingParticipantTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
function trustedMarketTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
function trustedUniverseTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
function trustedDisputeWindowTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
function getUniverse() public view returns (IUniverse);
function getTotalMigrated() public view returns (uint256);
function getTotalTheoreticalSupply() public view returns (uint256);
function mintForReportingParticipant(uint256 _amountMigrated) public returns (bool);
}
contract IShareToken is ITyped, IERC1155 {
function initialize(IAugur _augur) external;
function initializeMarket(IMarket _market, uint256 _numOutcomes, uint256 _numTicks) public;
function unsafeTransferFrom(address _from, address _to, uint256 _id, uint256 _value) public;
function unsafeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _values) public;
function claimTradingProceeds(IMarket _market, address _shareHolder, bytes32 _fingerprint) external returns (uint256[] memory _outcomeFees);
function getMarket(uint256 _tokenId) external view returns (IMarket);
function getOutcome(uint256 _tokenId) external view returns (uint256);
function getTokenId(IMarket _market, uint256 _outcome) public pure returns (uint256 _tokenId);
function getTokenIds(IMarket _market, uint256[] memory _outcomes) public pure returns (uint256[] memory _tokenIds);
function buyCompleteSets(IMarket _market, address _account, uint256 _amount) external returns (bool);
function buyCompleteSetsForTrade(IMarket _market, uint256 _amount, uint256 _longOutcome, address _longRecipient, address _shortRecipient) external returns (bool);
function sellCompleteSets(IMarket _market, address _holder, address _recipient, uint256 _amount, bytes32 _fingerprint) external returns (uint256 _creatorFee, uint256 _reportingFee);
function sellCompleteSetsForTrade(IMarket _market, uint256 _outcome, uint256 _amount, address _shortParticipant, address _longParticipant, address _shortRecipient, address _longRecipient, uint256 _price, address _sourceAccount, bytes32 _fingerprint) external returns (uint256 _creatorFee, uint256 _reportingFee);
function totalSupplyForMarketOutcome(IMarket _market, uint256 _outcome) public view returns (uint256);
function balanceOfMarketOutcome(IMarket _market, uint256 _outcome, address _account) public view returns (uint256);
function lowestBalanceOfMarketOutcomes(IMarket _market, uint256[] memory _outcomes, address _account) public view returns (uint256);
}
contract IUniverse {
function creationTime() external view returns (uint256);
function marketBalance(address) external view returns (uint256);
function fork() public returns (bool);
function updateForkValues() public returns (bool);
function getParentUniverse() public view returns (IUniverse);
function createChildUniverse(uint256[] memory _parentPayoutNumerators) public returns (IUniverse);
function getChildUniverse(bytes32 _parentPayoutDistributionHash) public view returns (IUniverse);
function getReputationToken() public view returns (IV2ReputationToken);
function getForkingMarket() public view returns (IMarket);
function getForkEndTime() public view returns (uint256);
function getForkReputationGoal() public view returns (uint256);
function getParentPayoutDistributionHash() public view returns (bytes32);
function getDisputeRoundDurationInSeconds(bool _initial) public view returns (uint256);
function getOrCreateDisputeWindowByTimestamp(uint256 _timestamp, bool _initial) public returns (IDisputeWindow);
function getOrCreateCurrentDisputeWindow(bool _initial) public returns (IDisputeWindow);
function getOrCreateNextDisputeWindow(bool _initial) public returns (IDisputeWindow);
function getOrCreatePreviousDisputeWindow(bool _initial) public returns (IDisputeWindow);
function getOpenInterestInAttoCash() public view returns (uint256);
function getTargetRepMarketCapInAttoCash() public view returns (uint256);
function getOrCacheValidityBond() public returns (uint256);
function getOrCacheDesignatedReportStake() public returns (uint256);
function getOrCacheDesignatedReportNoShowBond() public returns (uint256);
function getOrCacheMarketRepBond() public returns (uint256);
function getOrCacheReportingFeeDivisor() public returns (uint256);
function getDisputeThresholdForFork() public view returns (uint256);
function getDisputeThresholdForDisputePacing() public view returns (uint256);
function getInitialReportMinValue() public view returns (uint256);
function getPayoutNumerators() public view returns (uint256[] memory);
function getReportingFeeDivisor() public view returns (uint256);
function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
function getWinningChildPayoutNumerator(uint256 _outcome) public view returns (uint256);
function isOpenInterestCash(address) public view returns (bool);
function isForkingMarket() public view returns (bool);
function getCurrentDisputeWindow(bool _initial) public view returns (IDisputeWindow);
function getDisputeWindowStartTimeAndDuration(uint256 _timestamp, bool _initial) public view returns (uint256, uint256);
function isParentOf(IUniverse _shadyChild) public view returns (bool);
function updateTentativeWinningChildUniverse(bytes32 _parentPayoutDistributionHash) public returns (bool);
function isContainerForDisputeWindow(IDisputeWindow _shadyTarget) public view returns (bool);
function isContainerForMarket(IMarket _shadyTarget) public view returns (bool);
function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
function migrateMarketOut(IUniverse _destinationUniverse) public returns (bool);
function migrateMarketIn(IMarket _market, uint256 _cashBalance, uint256 _marketOI) public returns (bool);
function decrementOpenInterest(uint256 _amount) public returns (bool);
function decrementOpenInterestFromMarket(IMarket _market) public returns (bool);
function incrementOpenInterest(uint256 _amount) public returns (bool);
function getWinningChildUniverse() public view returns (IUniverse);
function isForking() public view returns (bool);
function deposit(address _sender, uint256 _amount, address _market) public returns (bool);
function withdraw(address _recipient, uint256 _amount, address _market) public returns (bool);
function createScalarMarket(uint256 _endTime, uint256 _feePerCashInAttoCash, IAffiliateValidator _affiliateValidator, uint256 _affiliateFeeDivisor, address _designatedReporterAddress, int256[] memory _prices, uint256 _numTicks, string memory _extraInfo) public returns (IMarket _newMarket);
}
contract IV2ReputationToken is IReputationToken {
function parentUniverse() external returns (IUniverse);
function burnForMarket(uint256 _amountToBurn) public returns (bool);
function mintForWarpSync(uint256 _amountToMint, address _target) public returns (bool);
}
contract IAugurTrading {
function lookup(bytes32 _key) public view returns (address);
function logProfitLossChanged(IMarket _market, address _account, uint256 _outcome, int256 _netPosition, uint256 _avgPrice, int256 _realizedProfit, int256 _frozenFunds, int256 _realizedCost) public returns (bool);
function logOrderCreated(IUniverse _universe, bytes32 _orderId, bytes32 _tradeGroupId) public returns (bool);
function logOrderCanceled(IUniverse _universe, IMarket _market, address _creator, uint256 _tokenRefund, uint256 _sharesRefund, bytes32 _orderId) public returns (bool);
function logOrderFilled(IUniverse _universe, address _creator, address _filler, uint256 _price, uint256 _fees, uint256 _amountFilled, bytes32 _orderId, bytes32 _tradeGroupId) public returns (bool);
function logMarketVolumeChanged(IUniverse _universe, address _market, uint256 _volume, uint256[] memory _outcomeVolumes, uint256 _totalTrades) public returns (bool);
function logZeroXOrderFilled(IUniverse _universe, IMarket _market, bytes32 _orderHash, bytes32 _tradeGroupId, uint8 _orderType, address[] memory _addressData, uint256[] memory _uint256Data) public returns (bool);
function logZeroXOrderCanceled(address _universe, address _market, address _account, uint256 _outcome, uint256 _price, uint256 _amount, uint8 _type, bytes32 _orderHash) public;
}
contract IOrders {
function saveOrder(uint256[] calldata _uints, bytes32[] calldata _bytes32s, Order.Types _type, IMarket _market, address _sender) external returns (bytes32 _orderId);
function removeOrder(bytes32 _orderId) external returns (bool);
function getMarket(bytes32 _orderId) public view returns (IMarket);
function getOrderType(bytes32 _orderId) public view returns (Order.Types);
function getOutcome(bytes32 _orderId) public view returns (uint256);
function getAmount(bytes32 _orderId) public view returns (uint256);
function getPrice(bytes32 _orderId) public view returns (uint256);
function getOrderCreator(bytes32 _orderId) public view returns (address);
function getOrderSharesEscrowed(bytes32 _orderId) public view returns (uint256);
function getOrderMoneyEscrowed(bytes32 _orderId) public view returns (uint256);
function getOrderDataForCancel(bytes32 _orderId) public view returns (uint256, uint256, Order.Types, IMarket, uint256, address);
function getOrderDataForLogs(bytes32 _orderId) public view returns (Order.Types, address[] memory _addressData, uint256[] memory _uint256Data);
function getBetterOrderId(bytes32 _orderId) public view returns (bytes32);
function getWorseOrderId(bytes32 _orderId) public view returns (bytes32);
function getBestOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
function getWorstOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
function getLastOutcomePrice(IMarket _market, uint256 _outcome) public view returns (uint256);
function getOrderId(Order.Types _type, IMarket _market, uint256 _amount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) public pure returns (bytes32);
function getTotalEscrowed(IMarket _market) public view returns (uint256);
function isBetterPrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
function isWorsePrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
function assertIsNotBetterPrice(Order.Types _type, uint256 _price, bytes32 _betterOrderId) public view returns (bool);
function assertIsNotWorsePrice(Order.Types _type, uint256 _price, bytes32 _worseOrderId) public returns (bool);
function recordFillOrder(bytes32 _orderId, uint256 _sharesFilled, uint256 _tokensFilled, uint256 _fill) external returns (bool);
function setPrice(IMarket _market, uint256 _outcome, uint256 _price) external returns (bool);
}
library Order {
using SafeMathUint256 for uint256;
enum Types {
Bid, Ask
}
enum TradeDirections {
Long, Short
}
struct Data {
IMarket market;
IAugur augur;
IAugurTrading augurTrading;
IShareToken shareToken;
ICash cash;
bytes32 id;
address creator;
uint256 outcome;
Order.Types orderType;
uint256 amount;
uint256 price;
uint256 sharesEscrowed;
uint256 moneyEscrowed;
bytes32 betterOrderId;
bytes32 worseOrderId;
}
function create(IAugur _augur, IAugurTrading _augurTrading, address _creator, uint256 _outcome, Order.Types _type, uint256 _attoshares, uint256 _price, IMarket _market, bytes32 _betterOrderId, bytes32 _worseOrderId) internal view returns (Data memory) {
require(_outcome < _market.getNumberOfOutcomes(), "Order.create: Outcome is not within market range");
require(_price != 0, "Order.create: Price may not be 0");
require(_price < _market.getNumTicks(), "Order.create: Price is outside of market range");
require(_attoshares > 0, "Order.create: Cannot use amount of 0");
require(_creator != address(0), "Order.create: Creator is 0x0");
IShareToken _shareToken = IShareToken(_augur.lookup("ShareToken"));
return Data({
market: _market,
augur: _augur,
augurTrading: _augurTrading,
shareToken: _shareToken,
cash: ICash(_augur.lookup("Cash")),
id: 0,
creator: _creator,
outcome: _outcome,
orderType: _type,
amount: _attoshares,
price: _price,
sharesEscrowed: 0,
moneyEscrowed: 0,
betterOrderId: _betterOrderId,
worseOrderId: _worseOrderId
});
}
function getOrderId(Order.Data memory _orderData, IOrders _orders) internal view returns (bytes32) {
if (_orderData.id == bytes32(0)) {
bytes32 _orderId = calculateOrderId(_orderData.orderType, _orderData.market, _orderData.amount, _orderData.price, _orderData.creator, block.number, _orderData.outcome, _orderData.moneyEscrowed, _orderData.sharesEscrowed);
require(_orders.getAmount(_orderId) == 0, "Order.getOrderId: New order had amount. This should not be possible");
_orderData.id = _orderId;
}
return _orderData.id;
}
function calculateOrderId(Order.Types _type, IMarket _market, uint256 _amount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) internal pure returns (bytes32) {
return sha256(abi.encodePacked(_type, _market, _amount, _price, _sender, _blockNumber, _outcome, _moneyEscrowed, _sharesEscrowed));
}
function getOrderTradingTypeFromMakerDirection(Order.TradeDirections _creatorDirection) internal pure returns (Order.Types) {
return (_creatorDirection == Order.TradeDirections.Long) ? Order.Types.Bid : Order.Types.Ask;
}
function getOrderTradingTypeFromFillerDirection(Order.TradeDirections _fillerDirection) internal pure returns (Order.Types) {
return (_fillerDirection == Order.TradeDirections.Long) ? Order.Types.Ask : Order.Types.Bid;
}
function saveOrder(Order.Data memory _orderData, bytes32 _tradeGroupId, IOrders _orders) internal returns (bytes32) {
getOrderId(_orderData, _orders);
uint256[] memory _uints = new uint256[](5);
_uints[0] = _orderData.amount;
_uints[1] = _orderData.price;
_uints[2] = _orderData.outcome;
_uints[3] = _orderData.moneyEscrowed;
_uints[4] = _orderData.sharesEscrowed;
bytes32[] memory _bytes32s = new bytes32[](4);
_bytes32s[0] = _orderData.betterOrderId;
_bytes32s[1] = _orderData.worseOrderId;
_bytes32s[2] = _tradeGroupId;
_bytes32s[3] = _orderData.id;
return _orders.saveOrder(_uints, _bytes32s, _orderData.orderType, _orderData.market, _orderData.creator);
}
}
interface IUniswapV2Factory {
event PairCreated(address indexed token0, address indexed token1, address pair, uint);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function getPair(address tokenA, address tokenB) external view returns (address pair);
function allPairs(uint) external view returns (address pair);
function allPairsLength() external view returns (uint);
function createPair(address tokenA, address tokenB) external returns (address pair);
function setFeeTo(address) external;
function setFeeToSetter(address) external;
}
interface IUniswapV2Pair {
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint);
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
event Mint(address indexed sender, uint amount0, uint amount1);
event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
event Swap(
address indexed sender,
uint amount0In,
uint amount1In,
uint amount0Out,
uint amount1Out,
address indexed to
);
event Sync(uint112 reserve0, uint112 reserve1);
function MINIMUM_LIQUIDITY() external pure returns (uint);
function factory() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function price0CumulativeLast() external view returns (uint);
function price1CumulativeLast() external view returns (uint);
function kLast() external view returns (uint);
function mint(address to) external returns (uint liquidity);
function burn(address to) external returns (uint amount0, uint amount1);
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function skim(address to) external;
function sync() external;
function initialize(address, address) external;
}
interface IWETH {
function deposit() external payable;
function balanceOf(address owner) external view returns (uint);
function transfer(address to, uint value) external returns (bool);
function withdraw(uint) external;
}
contract AugurWalletRegistry is Initializable, GSNRecipient {
using LibBytes for bytes;
using ContractExists for address;
using SafeMathUint256 for uint256;
enum GSNRecipientERC20FeeErrorCodes {
OK,
TX_COST_TOO_HIGH,
INSUFFICIENT_BALANCE
}
event ExecuteTransactionStatus(bool success, bool fundingSuccess);
IAugur public augur;
IAugurTrading public augurTrading;
IERC20 public cash;
IUniswapV2Pair public ethExchange;
IWETH public WETH;
bool public token0IsCash;
IAugurWalletFactory public augurWalletFactory;
uint256 private constant MAX_APPROVAL_AMOUNT = 2 ** 256 - 1;
uint256 private constant MAX_TX_FEE_IN_ETH = 10**17;
function initialize(IAugur _augur, IAugurTrading _augurTrading) public payable beforeInitialized returns (bool) {
require(msg.value >= MAX_TX_FEE_IN_ETH, "Must provide initial Max TX Fee Deposit");
endInitialization();
augur = _augur;
cash = IERC20(_augur.lookup("Cash"));
augurTrading = _augurTrading;
WETH = IWETH(_augurTrading.lookup("WETH9"));
augurWalletFactory = IAugurWalletFactory(_augurTrading.lookup("AugurWalletFactory"));
IUniswapV2Factory _uniswapFactory = IUniswapV2Factory(_augur.lookup("UniswapV2Factory"));
address _ethExchangeAddress = _uniswapFactory.getPair(address(WETH), address(cash));
if (_ethExchangeAddress == address(0)) {
_ethExchangeAddress = _uniswapFactory.createPair(address(WETH), address(cash));
}
ethExchange = IUniswapV2Pair(_ethExchangeAddress);
token0IsCash = ethExchange.token0() == address(cash);
IRelayHub(getHubAddr()).depositFor.value(address(this).balance)(address(this));
return true;
}
function acceptRelayedCall(
address,
address _from,
bytes calldata _encodedFunction,
uint256,
uint256,
uint256,
uint256,
bytes calldata,
uint256 _maxPossibleCharge
)
external
view
returns (uint256 _reason, bytes memory _context)
{
uint256 _payment = getPaymentFromEncodedFunction(_encodedFunction);
GSNRecipientERC20FeeErrorCodes _code = getAcceptRelayCallStatus(_from, _payment, _maxPossibleCharge);
if (_code != GSNRecipientERC20FeeErrorCodes.OK) {
return _rejectRelayedCall(uint256(_code));
}
uint256 _initialEth = address(this).balance;
return _approveRelayedCall(abi.encode(_from, _initialEth));
}
function getPaymentFromEncodedFunction(bytes memory _encodedFunction) private pure returns (uint256) {
bytes memory _encodedFunctionParams = _encodedFunction.sliceDestructive(4, _encodedFunction.length);
(address _to, bytes memory _data, uint256 _value, uint256 _payment, address _affilate, bytes32 _fingerprint) = abi.decode(_encodedFunctionParams, (address, bytes, uint256, uint256, address, bytes32));
return _payment;
}
function getAcceptRelayCallStatus(address _from, uint256 _payment, uint256 _maxPossibleCharge) private view returns (GSNRecipientERC20FeeErrorCodes _code) {
(uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = ethExchange.getReserves();
uint256 _maxDaiNeeded = getAmountIn(_maxPossibleCharge, token0IsCash ? _reserve0 : _reserve1, token0IsCash ? _reserve1 : _reserve0);
if (_maxDaiNeeded > _payment) {
return GSNRecipientERC20FeeErrorCodes.TX_COST_TOO_HIGH;
}
if (cash.balanceOf(getCreate2WalletAddress(_from)) < _payment) {
return GSNRecipientERC20FeeErrorCodes.INSUFFICIENT_BALANCE;
}
return GSNRecipientERC20FeeErrorCodes.OK;
}
function _preRelayedCall(bytes memory _context) internal returns (bytes32) { }
function _postRelayedCall(bytes memory _context, bool, uint256 _actualCharge, bytes32) internal {
(address _from, uint256 _initialEth) = abi.decode(_context, (address, uint256));
uint256 _ethPaid = address(this).balance.sub(_initialEth);
uint256 _ethRefund = _ethPaid.sub(_actualCharge);
(bool _success,) = address(_from).call.value(_ethRefund)("");
require(_success);
uint256 _depositAmount = address(this).balance;
_depositAmount = _depositAmount.min(2 ether);
IRelayHub(getHubAddr()).depositFor.value(_depositAmount)(address(this));
}
function getEthFromWallet(IAugurWallet _wallet, uint256 _cashAmount) private {
(uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = ethExchange.getReserves();
uint256 _ethAmount = getAmountOut(_cashAmount, token0IsCash ? _reserve0 : _reserve1, token0IsCash ? _reserve1 : _reserve0);
_wallet.transferCash(address(ethExchange), _cashAmount);
ethExchange.swap(token0IsCash ? 0 : _ethAmount, token0IsCash ? _ethAmount : 0, address(this), "");
WETH.withdraw(_ethAmount);
}
function fundMsgSender(uint256 _desiredSignerBalance, uint256 _maxExchangeRateInDai) private returns (bool) {
address _msgSender = address(_msgSender());
IAugurWallet _wallet = getWallet(_msgSender);
uint256 _msgSenderBalance = _msgSender.balance;
if (_msgSenderBalance >= _desiredSignerBalance) {
return true;
}
uint256 _ethDelta = _desiredSignerBalance - _msgSenderBalance;
(uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = ethExchange.getReserves();
uint256 _cashAmount = getAmountIn(_ethDelta, token0IsCash ? _reserve0 : _reserve1, token0IsCash ? _reserve1 : _reserve0);
uint256 _exchangeRate = _cashAmount.mul(10**18).div(_ethDelta);
if (_maxExchangeRateInDai < _exchangeRate) {
return false;
}
_wallet.transferCash(address(ethExchange), _cashAmount);
ethExchange.swap(token0IsCash ? 0 : _ethDelta, token0IsCash ? _ethDelta : 0, address(this), "");
WETH.withdraw(_ethDelta);
(bool _success,) = _msgSender.call.value(_ethDelta)("");
return _success;
}
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) public pure returns (uint amountOut) {
require(amountIn > 0);
require(reserveIn > 0 && reserveOut > 0);
uint amountInWithFee = amountIn.mul(997);
uint numerator = amountInWithFee.mul(reserveOut);
uint denominator = reserveIn.mul(1000).add(amountInWithFee);
amountOut = numerator / denominator;
}
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) public pure returns (uint amountIn) {
require(amountOut > 0);
require(reserveIn > 0 && reserveOut > 0);
uint numerator = reserveIn.mul(amountOut).mul(1000);
uint denominator = reserveOut.sub(amountOut).mul(997);
amountIn = (numerator / denominator).add(1);
}
function createAugurWallet(address _referralAddress, bytes32 _fingerprint) private returns (IAugurWallet) {
return augurWalletFactory.createAugurWallet(_msgSender(), _referralAddress, _fingerprint);
}
function getCreate2WalletAddress(address _owner) public view returns (address) {
return augurWalletFactory.getCreate2WalletAddress(_owner);
}
function getWallet(address _account) public view returns (IAugurWallet) {
address _walletAddress = getCreate2WalletAddress(_account);
if (!_walletAddress.exists()) {
return IAugurWallet(0);
}
return IAugurWallet(_walletAddress);
}
function executeWalletTransaction(address _to, bytes calldata _data, uint256 _value, uint256 _payment, address _referralAddress, bytes32 _fingerprint, uint256 _desiredSignerBalance, uint256 _maxExchangeRateInDai, bool _revertOnFailure) external {
address _user = _msgSender();
IAugurWallet _wallet = getWallet(_user);
if (_wallet == IAugurWallet(0)) {
_wallet = createAugurWallet(_referralAddress, _fingerprint);
}
if (_user != msg.sender) {
getEthFromWallet(_wallet, _payment);
}
bool _success = _wallet.executeTransaction(_to, _data, _value);
if (_user == msg.sender && _revertOnFailure) {
require(_success, "Transaction Execution Failed");
}
bool _fundingSuccess = fundMsgSender(_desiredSignerBalance, _maxExchangeRateInDai);
emit ExecuteTransactionStatus(_success, _fundingSuccess);
}
function getRelayMessageHash(
address relay,
address from,
address to,
bytes memory encodedFunction,
uint256 transactionFee,
uint256 gasPrice,
uint256 gasLimit,
uint256 nonce) public view returns (bytes32) {
bytes memory packed = abi.encodePacked("rlx:", from, to, encodedFunction, transactionFee, gasPrice, gasLimit, nonce, getHubAddr());
return keccak256(abi.encodePacked(packed, relay));
}
function () external payable {}
}