Deposit Contract¶
Description¶
Deposit contracts are the Ethereum smart contracts into which assets are deposited–custodying the money as it is transacted on plasma and playing out the exit games to resolve the rightful owners of previously deposited assets. As such, it contains the bulk of the logic for the plasma exit games. The things it does not cover are 1) block commitments, and 2), state deprecation, which are handled by calls to the commitment contract and predicate contracts specifically.
API¶
Structs¶
Range¶
struct Range {
uint256 start;
uint256 end;
}
Description¶
Represents a range of state objects.
Fields¶
start
-uint256
: Start of the range of objects.end
-uint256
: End of the range of objects.
StateObject¶
struct StateObject {
string id;
address predicate;
bytes data;
}
Description¶
Represents a state object. Contains the address of the predicate contract and input data to that contract which control the conditions under which the object may be mutated.
Fields¶
id
-string
: A globally unique identifier for this state object.predicateAddress
-address
: Address of the predicate contract that dictates how the object can be mutated.data
-bytes
: Arbitrary state data for the object.
StateUpdate¶
struct StateUpdate {
Range range;
StateObject stateObject;
address plasmaContract;
uint256 plasmaBlockNumber;
}
Description¶
Represents a state update, which contains the contextual information for how a particular range of state objects was mutated.
Fields¶
range
-Range
: Range of state objects that were mutated.stateObject
-StateObject
: Resulting state object created by the mutation of the input objects.plasmaContract
-address
: Address of the plasma contract in which the update was included.plasmaBlockNumber
-uint256
: Plasma block number in which the update occurred.
Checkpoint¶
struct Checkpoint {
StateUpdate stateUpdate;
Range subRange;
}
Description¶
Represents a checkpoint of a particular state update on which a “checkpoint game” is being or has been played out. Checkpoints which have successfully passed the checkpoint game are considered “finalized”, meaning the plasma contract should ignore all state updates on that range with an older plasma block number.
Fields¶
stateUpdate
-StateUpdate
: State update being checkpointed.subRange
-Range
: Sub-range of the state update being checkpointed. We include this field because the update may be partially spent.
CheckpointStatus¶
struct CheckpointStatus {
uint256 challengeableUntil;
uint256 outstandingChallenges;
}
Description¶
Status of a particular checkpoint attempt.
Fields¶
challengeableUntil
-uint256
: Ethereum block number until which the checkpoint can still be challenged.outstandingChallenges
-uint256
: Number of outstanding challenges.
Challenge¶
struct Challenge {
Checkpoint challengedCheckpoint;
Checkpoint challengingCheckpoint;
}
Description¶
Describes a challenge against a checkpoint. A challenge is a claim that the challengingCheckpoint
has no valid transactions, meaning that the state update in the challengedCheckpoint
could never have been reached and thus is invalid.
Fields¶
challengedCheckpoint
-Checkpoint
: Checkpoint being challenged.challengingCheckpoint
-Checkpoint
: Checkpoint being used to challenge.
Public Variables¶
COMMITMENT_ADDRESS¶
address constant COMMITMENT_ADDRESS;
Description¶
Address of the commitment contract where block headers for the plasma chain are being published.
Requirements¶
Deposit contracts MUST specify the address of a commitment contract where plasma chain block headers are being published.
Rationale¶
Deposit contracts handle deposits and exits from a specific plasma chain. Commitment contracts hold the plasma block headers for that plasma chain and therefore make it possible to verify inclusion proofs.
TOKEN_ADDRESS¶
address constant TOKEN_ADDRESS;
Description¶
Address of the ERC-20 token which this deposit contract custodies.
Requirements¶
- The deposit contract:
- MUST only support deposits of a single ERC-20 token.
TOKEN_ADDRESS
:- MUST be the address of an ERC-20 token.
Rationale¶
Each asset type needs to be allocated its own large contiguous “sub-range” within the larger Plasma Cashflow chain. Without these sub-ranges, defragmentation becomes effectively impossible. Although it’s possible to achieve this result within a single deposit contract, it’s easier to simply require that each asset have its own deposit contract and to allocate a large sub-range to every deposit contract.
CHALLENGE_PERIOD¶
uint256 constant CHALLENGE_PERIOD;
Description¶
Number of Ethereum blocks for which a checkpoint may be challenged.
EXIT_PERIOD¶
uint256 constant EXIT_PERIOD;
Description¶
Number of Ethereum blocks before an exit can be finalized.
totalDeposited¶
uint256 public totalDeposited;
Description¶
Total amount deposited into this contract.
checkpoints¶
mapping (bytes32 => CheckpointStatus) public checkpoints;
Description¶
Mapping from the ID of a checkpoint to the checkpoint’s status.
depositedRanges¶
mapping (uint256 => Range) public depositedRanges;
Description¶
Stores the list of ranges that have not been exited as a mapping from the start
of a range to the full range. Prevents multiple exits from the same range of objects.
exitRedeemableAfter¶
mapping (bytes32 => uint256) public exitRedeemableAfter;
Description¶
Mapping from the ID of an exit to the Ethereum block after which the exit can be finalized.
challenges¶
mapping (bytes32 => bool) public challenges;
Description¶
Mapping from the ID of a challenge to whether or not the challenge is currently active.
Events¶
CheckpointStarted¶
event CheckpointStarted(
Checkpoint checkpoint,
uint256 challengeableUntil
);
Description¶
Emitted whenever a user attempts to checkpoint a state update.
Fields¶
checkpoint
-bytes32
: ID of the checkpoint that was started.challengeableUntil
-uint256
: Ethereum block in which the checkpoint was started.
CheckpointChallenged¶
event CheckpointChallenged(
Challenge challenge
);
Description¶
Emitted whenever an invalid history challenge has been started on a checkpoint.
CheckpointFinalized¶
event CheckpointFinalized(
bytes32 checkpoint
);
Description¶
Emitted whenever a checkpoint is finalized.
Fields¶
checkpoint
-bytes32
: ID of the checkpoint that was finalized.
ExitStarted¶
event ExitStarted(
bytes32 exit,
uint256 redeemableAfter
);
Description¶
Emitted whenever an exit is started.
Fields¶
exit
-bytes32
: ID of the exit that was started.redeembleAfter
-uint256
: Ethereum block in which the exit will be redeemable.
ExitFinalized¶
event ExitFinalized(
Checkpoint exit
);
Description¶
Emitted whenever an exit is finalized.
Fields¶
exit
-Checkpoint
: The checkpoint that had its exit finalized.
Methods¶
deposit¶
function deposit(
address _depositer,
uint256 _amount,
StateObject _initialState
) public
Description¶
Allows a user to submit a deposit to the contract. Only allows users to submit deposits for the asset represented by this contract.
Parameters¶
_depositer
-address
: the account which has approved the ERC20 deposit._amount
-uint256
: Amount of the asset to deposit._initialState
-StateObject
: Initial state to put the deposited assets into. Can be any valid state object.
Requirements¶
- MUST keep track of the total deposited assets,
totalDeposited
. - MUST transfer the deposited
amount
from thedepositer
to the deposit contract’s address. - MUST create a state update with a state object equal to the provided
initialState
. - MUST compute the range of the created state update as
totalDeposited
tototalDeposited + amount
. - MUST update the total amount deposited after the deposit is handled.
- MUST insert the created state update into the
checkpoints
mapping withchallengeableUntil
being the current block number - 1. - MUST emit a
CheckpointFinalized
event for the inserted checkpoint.
Rationale¶
Depositing is the mechanism which locks an asset into the plasma escrow agreement, allowing it to be transacted off-chain. The initialState
defines its spending conditions, in the same way that a StateUpdate
does once further transactions are made. Because deposits are verified on-chain transactions, they can be treated as checkpoints which are unchallengeable.
startCheckpoint¶
function startCheckpoint(
Checkpoint _checkpoint,
bytes _inclusionProof,
uint256 _depositedRangeId
) public
Description¶
Starts a checkpoint for a given state update.
Parameters¶
_checkpoint
-Checkpoint
: Checkpoint to be initiated._inclusionProof
-bytes
: Proof that the state update was included in the block specified within the update._depositedRangeId
-uint256
: The key in thedepositedRanges
mapping which includes thesubRange
as a subrange.
Requirements¶
- MUST verify the that
checkpoint.stateUpdate
was included withinclusionProof
. - MUST verify that
subRange
is actually a sub-range ofstateUpdate.range
. - MUST verify that the
subRange
is still exitable with thedepositedRangeId
. - MUST verify that an indentical checkpoint has not already been started.
- MUST add the new pending checkpoint to
checkpoints
withchallengeableUntil
equalling the current ethereumblock.number + CHALLENGE_PERIOD
. - MUST emit a
CheckpointStarted
event.
Rationale¶
Checkpoints are assertions that a certain state update occured/was included, and that it has no intersecting unspent state updates in its history. Because the operator may publish an invalid block, it must undergo a challenge period in which the parties who care about the unspent state update in the history exit it, and use it to challenge the checkpoint.
deleteExitOutdated¶
function deleteExitOutdated(
Checkpoint _olderExitt,
Checkpoint _newerCheckpoint
) public
Description¶
Deletes an exit by showing that there exists a newer finalized checkpoint. Immediately cancels the exit.
Parameters¶
_olderExitt
-Checkpoint
: `The exit`_ to delete._newerCheckpoint
-Checkpoint
: The checkpoint used to challenge.
Requirements¶
- MUST ensure the checkpoint ranges intersect.
- MUST ensure that the plasma blocknumber of the
_olderExitt
is less than that of_newerCheckpoint
. - MUST ensure that the
newerCheckpoint
has no challenges. - MUST ensure that the
newerCheckpoint
is no longer challengeable. - MUST delete the entries in
exitRedeemableAfter
.
Rationale¶
If a checkpoint game has finalized, the safety property should be that nothing is valid in that range’s previous blocks–”the history has been erased.” However, since there still might be some StateUpdates
included in the blocks prior, invalid checkpoints can be initiated. This method allows the rightful owner to demonstrate that the initiated olderCheckpoint
is invalid and must be deleted.
challengeCheckpoint¶
function challengeCheckpoint(
Challenge _challenge
) public
Description¶
Starts a challenge for a checkpoint by pointing to an exit that occurred in an earlier plasma block. Does not immediately cancel the checkpoint. Challenge can be blocked if the exit is cancelled.
Parameters¶
_challenge
-Challenge
: Challenge to submit.
Requirements¶
- MUST ensure that the checkpoint being used to challenge exists.
- MUST ensure that the challenge ranges intersect.
- MUST ensure that the checkpoint being used to challenge has an older
plasmaBlockNumber
. - MUST ensure that an identical challenge is not already underway.
- MUST ensure that the current ethereum block is not greater than the
challengeableUntil
block for the checkpoint being challenged. - MUST increment the
outstandingChallenges
for the challenged checkpoint. - MUST set the
challenges
mapping for thechallengeId
to true.
Rationale¶
If the operator includes an invalid StateUpdate
(i.e. there is not a deprecation for the last valid StateUpdate
on an intersecting range), they may checkpoint it and attempt a malicious exit. To prevent this, the valid owner must checkpoint their unspent state, exit it, and create a challenge on the invalid checkpoint.
removeChallenge¶
function removeChallenge(
Challenge _challenge
) public
Description¶
Decrements the number of outstanding challenges on a checkpoint by showing that one of its challenges has been blocked.
Parameters¶
_challenge
-Challenge
: `The challenge`_ that was blocked.
Requirements¶
- MUST check that the challenge was not already removed.
- MUST check that the challenging exit has since been removed.
- MUST remove the challenge if above conditions are met.
- MUST decrement the challenged checkpoint’s
outstandingChallenges
if the above conditions are met.
Rationale¶
Anyone can exit a prior state which was since spent and use it to challenge despite it being deprecated. To remove this invalid challenge, the challenged checkpointer may demonstrate the exit is deprecated, deleting it, and then call this method to remove the challenge.
startExit¶
function startExit(Checkpoint _checkpoint) public
Description¶
Allows the predicate contract to start an exit from a checkpoint. Checkpoint may be pending or finalized.
Parameters¶
_checkpoint
-Checkpoint
: The checkpoint from which to exit.
Requirements¶
- MUST ensure the checkpoint exists.
- MUST ensure that the
msg.sender
is the_checkpoint.stateUpdate.predicateAddress
to authenticate the exit’s initiation. - MUST ensure an exit on the checkpoint is not already underway.
- MUST set the exit’s
redeemableAfter
status to the current Ethereumblock.number + LOCKUP_PERIOD
. - MUST emit an
exitStarted
event.
Rationale¶
For a user to redeem state from the plasma chain onto the main chain, they must checkpoint it and respond to all challenges on the checkpoint, and await a LOCKUP_PERIOD
to demonstrate that the checkpointed subrange has not been deprecated. This is the method which starts the latter process on a given checkpoint.
deprecateExit¶
function deprecateExit(
Checkpoint _checkpoint
) public
Description¶
Allows the predicate address to cancel an exit which it determines is deprecated.
Parameters¶
_checkpoint
-Checkpoint
: The checkpoint referenced by the exit.
Requirements¶
- MUST ensure the
msg.sender
is the_checkpoint.stateUpdate.predicateAddress
to ensure the deprecation is authenticated. - MUST delete the exit from
exitRedeemableAfter
at thecheckpointId
.
Rationale¶
If a transaction exists spending from a checkpoint, the checkpoint may still be valid, but an exit on it is not. This method allows the predicate to remove the exit if it has determined it to be outdated.
finalizeExit¶
function finalizeExit(Checkpoint _exit, uint256 _depositedRangeId) public
Description¶
Finalizes an exit that has passed its exit period and has not been successfully challenged.
Parameters¶
_exit
-Checkpoint
: The checkpoint on which the exit is not finalizable._depositedRangeId
-uint256
: the entry indepositedRanges
demonstrating the range is not yet exited.
Requirements¶
- MUST ensure that the exit finalization is authenticated from the predicate by
msg.sender == _exit.stateUpdate.state.predicateAddress
. - MUST ensure that the checkpoint is finalized (current Ethereum block exceeds
checkpoint.challengeableUntil
). - MUST ensure that the checkpoint’s
outstandingChallenges
is 0. - MUST ensure that the exit is finalized (current Ethereum block exceeds
redeemablAfter
). - MUST ensure that the checkpoint is on a subrange of the currently exitable ranges via
depositedRangeId
. - MUST make an ERC20 transfer of the
end - start
amount to the predicate address. - MUST delete the exit.
- MUST remove the exited range by updating the
depositedRanges
mapping. - MUST delete the checkpoint.
- MUST emit an
exitFinalized
event.
Rationale¶
Exit finalization is the step which actually allows the assets locked in plasma to be used on the main chain again. Finalization requires that the exit and checkpoint games have completed successfully.