Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
148 lines (128 sloc) 4.75 KB
pragma solidity ^0.5.2;
import { Common } from "../../common/lib/Common.sol";
import { RLPEncode } from "../../common/lib/RLPEncode.sol";
import { RLPReader } from "solidity-rlp/contracts/RLPReader.sol";
import { IWithdrawManager } from "../withdrawManager/IWithdrawManager.sol";
import { IDepositManager } from "../depositManager/IDepositManager.sol";
import { ExitsDataStructure } from "../withdrawManager/WithdrawManagerStorage.sol";
import { ChainIdMixin } from "../../common/mixin/ChainIdMixin.sol";
interface IPredicate {
* @notice Verify the deprecation of a state update
* @param exit ABI encoded PlasmaExit data
* @param inputUtxo ABI encoded Input UTXO data
* @param challengeData RLP encoded data of the challenge reference tx that encodes the following fields
* headerNumber Header block number of which the reference tx was a part of
* blockProof Proof that the block header (in the child chain) is a leaf in the submitted merkle root
* blockNumber Block number of which the reference tx is a part of
* blockTime Reference tx block time
* blocktxRoot Transactions root of block
* blockReceiptsRoot Receipts root of block
* receipt Receipt of the reference transaction
* receiptProof Merkle proof of the reference receipt
* branchMask Merkle proof branchMask for the receipt
* logIndex Log Index to read from the receipt
* tx Challenge transaction
* txProof Merkle proof of the challenge tx
* @return Whether or not the state is deprecated
function verifyDeprecation(bytes calldata exit, bytes calldata inputUtxo, bytes calldata challengeData) external returns (bool);
function interpretStateUpdate(bytes calldata state) external view returns (bytes memory);
function onFinalizeExit(bytes calldata data) external;
contract PredicateUtils is ExitsDataStructure, ChainIdMixin {
using RLPReader for RLPReader.RLPItem;
// Bonded exits collaterized at 0.1 ETH
uint256 constant private BOND_AMOUNT = 10 ** 17;
IWithdrawManager internal withdrawManager;
IDepositManager internal depositManager;
modifier onlyWithdrawManager() {
msg.sender == address(withdrawManager),
modifier isBondProvided() {
msg.value == BOND_AMOUNT,
"Invalid Bond amount"
function sendBond() internal {
function onFinalizeExit(bytes calldata data)
(, address token, address exitor, uint256 tokenId) = decodeExitForProcessExit(data);
depositManager.transferAssets(token, exitor, tokenId);
function getAddressFromTx(RLPReader.RLPItem[] memory txList)
returns (address signer, bytes32 txHash)
bytes[] memory rawTx = new bytes[](9);
for (uint8 i = 0; i <= 5; i++) {
rawTx[i] = txList[i].toBytes();
rawTx[6] = networkId;
rawTx[7] = hex""; // [7] and [8] have something to do with v, r, s values
rawTx[8] = hex"";
txHash = keccak256(RLPEncode.encodeList(rawTx));
signer = ecrecover(
Common.getV(txList[6].toBytes(), Common.toUint16(networkId)),
function decodeExit(bytes memory data)
returns (PlasmaExit memory)
(address owner, address token, uint256 amountOrTokenId, bytes32 txHash, bool isRegularExit) = abi.decode(data, (address, address, uint256, bytes32, bool));
return PlasmaExit(amountOrTokenId, txHash, owner, token, isRegularExit, address(0) /* predicate value is not required */);
function decodeExitForProcessExit(bytes memory data)
returns (uint256 exitId, address token, address exitor, uint256 tokenId)
(exitId, token, exitor, tokenId) = abi.decode(
data, (uint256, address, address, uint256)
function decodeInputUtxo(bytes memory data)
returns (uint256 age, address signer, address predicate, address token)
(age, signer, predicate, token) = abi.decode(data, (uint256, address, address, address));
contract IErcPredicate is IPredicate, PredicateUtils {
enum ExitType { Invalid, OutgoingTransfer, IncomingTransfer, Burnt }
struct ExitTxData {
uint256 amountOrToken;
bytes32 txHash;
address childToken;
address signer;
ExitType exitType;
struct ReferenceTxData {
uint256 closingBalance;
uint256 age;
address childToken;
address rootToken;
uint256 constant internal MAX_LOGS = 10;
constructor(address _withdrawManager, address _depositManager) public {
withdrawManager = IWithdrawManager(_withdrawManager);
depositManager = IDepositManager(_depositManager);
You can’t perform that action at this time.