Skip to content
This repository has been archived by the owner on Dec 13, 2019. It is now read-only.

Commit

Permalink
[contract] Interpreters
Browse files Browse the repository at this point in the history
  • Loading branch information
ldct committed Apr 13, 2019
1 parent 1ea2665 commit 51c45e5
Show file tree
Hide file tree
Showing 22 changed files with 133 additions and 332 deletions.
16 changes: 3 additions & 13 deletions packages/apps/contracts/CommitRevealApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ contract CommitRevealApp is CounterfactualApp {
function resolve(bytes memory encodedState, Transfer.Terms memory terms)
public
pure
returns (Transfer.Transaction memory)
returns (bytes memory)
{
AppState memory state = abi.decode(encodedState, (AppState));

Expand All @@ -115,23 +115,13 @@ contract CommitRevealApp is CounterfactualApp {
address[] memory to = new address[](1);
uint256 player;
if (state.stage == Stage.DONE) {
player = uint256(state.winner);
return abi.encodePacked(player);
} else {
// The player who is not the turn taker
player = 1 - uint256(
state.stage == Stage.GUESSING ? Player.GUESSING : Player.CHOOSING
);
}
to[0] = state.playerAddrs[player];

bytes[] memory data = new bytes[](2);

return Transfer.Transaction(
terms.assetType,
terms.token,
to,
amounts,
data
);
return abi.encodePacked(player);
}
}
19 changes: 2 additions & 17 deletions packages/apps/contracts/CountingApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,11 @@ contract CountingApp is CounterfactualApp {
function resolve(bytes memory encodedState, Transfer.Terms memory terms)
public
pure
returns (Transfer.Transaction memory)
returns (bytes memory)
{
AppState memory state = abi.decode(encodedState, (AppState));

uint256[] memory amounts = new uint256[](2);
amounts[0] = terms.limit;
amounts[1] = 0;

address[] memory to = new address[](2);
to[0] = state.player1;
to[1] = state.player2;
bytes[] memory data = new bytes[](2);

return Transfer.Transaction(
terms.assetType,
terms.token,
to,
amounts,
data
);
return abi.encodePacked(uint256(0));
}

function applyAction(bytes memory encodedState, bytes memory encodedAction)
Expand Down
43 changes: 11 additions & 32 deletions packages/apps/contracts/HighRollerApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ contract HighRollerApp is CounterfactualApp {
}

struct AppState {
address[2] playerAddrs;
Stage stage;
bytes32 salt;
bytes32 commitHash;
Expand Down Expand Up @@ -119,56 +118,36 @@ contract HighRollerApp is CounterfactualApp {
function resolve(bytes memory encodedState, Transfer.Terms memory terms)
public
pure
returns (Transfer.Transaction memory)
returns (bytes memory)
{
AppState memory state = abi.decode(encodedState, (AppState));
AppState memory appState = abi.decode(encodedState, (AppState));

uint256[] memory amounts = new uint256[](2);
address[] memory to = new address[](2);
to[0] = state.playerAddrs[0];
to[1] = state.playerAddrs[1];
bytes32 expectedCommitHash = keccak256(
abi.encodePacked(state.salt, state.playerFirstNumber)
abi.encodePacked(appState.salt, appState.playerFirstNumber)
);
if (expectedCommitHash == state.commitHash) {
amounts = getWinningAmounts(
state.playerFirstNumber, state.playerSecondNumber, terms.limit
if (expectedCommitHash == appState.commitHash) {
return getWinningAmounts(
appState.playerFirstNumber, appState.playerSecondNumber, terms.limit
);
} else {
amounts[0] = 0;
amounts[1] = terms.limit;
}

bytes[] memory data = new bytes[](2);

return Transfer.Transaction(
terms.assetType,
terms.token,
to,
amounts,
data
);
return abi.encodePacked(uint256(1));
}

function getWinningAmounts(uint256 num1, uint256 num2, uint256 termsLimit)
public
pure
returns (uint256[] memory)
returns (bytes memory)
{
uint256[] memory amounts = new uint256[](2);
bytes32 randomSalt = calculateRandomSalt(num1, num2);
(uint8 playerFirstTotal, uint8 playerSecondTotal) = highRoller(randomSalt);
if (playerFirstTotal > playerSecondTotal) {
amounts[0] = termsLimit;
amounts[1] = 0;
return abi.encodePacked(uint256(0));
} else if (playerFirstTotal < playerSecondTotal) {
amounts[0] = 0;
amounts[1] = termsLimit;
} else {
amounts[0] = termsLimit / 2;
amounts[1] = termsLimit / 2;
return abi.encodePacked(uint256(1));
}
return amounts;
return abi.encodePacked(uint256(2));
}

function highRoller(bytes32 randomness)
Expand Down
24 changes: 3 additions & 21 deletions packages/apps/contracts/NimApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ contract NimApp is CounterfactualApp {
}

struct AppState {
address[2] players;
uint256 turnNum;
uint256[3] pileHeights;
}
Expand Down Expand Up @@ -63,30 +62,13 @@ contract NimApp is CounterfactualApp {
function resolve(bytes memory encodedState, Transfer.Terms memory terms)
public
pure
returns (Transfer.Transaction memory)
returns (bytes memory)
{
AppState memory state = abi.decode(encodedState, (AppState));

require(isWin(state), "Resolution state was not in a winning position");
address loser = state.players[state.turnNum % 2];
address winner = state.players[1 - (state.turnNum % 2)];

uint256[] memory amounts = new uint256[](2);
amounts[0] = terms.limit;
amounts[1] = 0;

address[] memory to = new address[](2);
to[0] = loser;
to[1] = winner;
bytes[] memory data = new bytes[](2);

return Transfer.Transaction(
terms.assetType,
terms.token,
to,
amounts,
data
);

return abi.encodePacked(state.turnNum % 2);
}

function isWin(AppState memory state)
Expand Down
40 changes: 4 additions & 36 deletions packages/apps/contracts/TicTacToeApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -98,50 +98,18 @@ contract TicTacToeApp is CounterfactualApp {
return abi.encode(postState);
}

function resolve(bytes memory encodedState, Transfer.Terms memory terms)
function resolve(bytes memory encodedState)
public
pure
returns (Transfer.Transaction memory)
returns (bytes memory)
{
AppState memory state = abi.decode(encodedState, (AppState));
require(state.winner != 0, "Winner was set to 0; invalid");

uint256[] memory amounts = new uint256[](2);
address[] memory to = new address[](2);
bytes[] memory data = new bytes[](2);

if (state.winner == 3) {
amounts[0] = terms.limit / 2;
amounts[1] = terms.limit / 2;

to[0] = state.players[0];
to[1] = state.players[1];

return Transfer.Transaction(
terms.assetType,
terms.token,
to,
amounts,
data
);

return abi.encodePacked(uint256(2));
} else {
address winner = state.players[state.winner - 1];
address loser = state.players[2 - state.winner];

amounts[0] = terms.limit;
amounts[1] = 0;

to[0] = winner;
to[1] = loser;

return Transfer.Transaction(
terms.assetType,
terms.token,
to,
amounts,
data
);
return abi.encodePacked(state.winner - 1);
}

}
Expand Down
2 changes: 1 addition & 1 deletion packages/apps/waffle.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var waffleConfig = {
};

var selectSolc = () => {
if (process.env.CI || process.env.NATIVE_SOLC == "true") {
if (1) {
// use native solc binary for fast compilation in CI
waffleConfig.compiler = "native";

Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/contracts/CounterfactualApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ contract CounterfactualApp {
function resolve(bytes memory, Transfer.Terms memory)
public
pure
returns (Transfer.Transaction memory);
returns (bytes memory);

}
16 changes: 4 additions & 12 deletions packages/contracts/contracts/ETHVirtualAppAgreement.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,13 @@ contract ETHVirtualAppAgreement {
"agreement lockup time has not elapsed"
);

Transfer.Transaction memory resolution = agreement.registry
bytes memory resolution = agreement.registry
.getResolution(agreement.appIdentityHash);

require(
agreement.terms.assetType == resolution.assetType,
"returned incompatible resolution based on bad asset type"
);

require(
agreement.terms.token == resolution.token,
"returned incompatible resolution based on bad token value"
);
uint256 resolutionAsValue = abi.decode(resolution, (uint256));

require(
agreement.capitalProvided > resolution.value[0],
agreement.capitalProvided > resolutionAsValue,
"returned incompatible resolution"
);

Expand All @@ -65,7 +57,7 @@ contract ETHVirtualAppAgreement {

uint256[] memory amount = new uint256[](2);

amount[0] = resolution.value[0];
amount[0] = resolutionAsValue;
amount[1] = agreement.capitalProvided - amount[0];

bytes[] memory data = new bytes[](2);
Expand Down
11 changes: 11 additions & 0 deletions packages/contracts/contracts/Interpreter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
pragma solidity 0.5.7;
pragma experimental "ABIEncoderV2";

import "./libs/Transfer.sol";


contract Interpreter {

function interpret(bytes memory, bytes memory)
public;
}
18 changes: 7 additions & 11 deletions packages/contracts/contracts/StateChannelTransaction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "./libs/Transfer.sol";

import "./NonceRegistry.sol";
import "./AppRegistry.sol";
import "./Interpreter.sol";


/// @title StateChannelTransaction
Expand All @@ -13,19 +14,17 @@ import "./AppRegistry.sol";
/// @notice Supports a complex transfer of funds contingent on some condition.
contract StateChannelTransaction {

using Transfer for Transfer.Transaction;

/// @notice Execute a fund transfer for a state channel app in a finalized state
/// @param uninstallKey The key in the nonce registry
/// @param appIdentityHash AppIdentityHash to be resolved
/// @param terms The pre-agreed upon terms of the funds transfer
function executeAppConditionalTransaction(
AppRegistry appRegistry,
NonceRegistry nonceRegistry,
bytes32 uninstallKey,
uint256 rootNonceExpectedValue,
bytes32 appIdentityHash,
Transfer.Terms memory terms
address interpreterAddress,
bytes memory interpreterParams
)
public
{
Expand All @@ -48,16 +47,13 @@ contract StateChannelTransaction {
"App is not finalized yet"
);

Transfer.Transaction memory txn = appRegistry.getResolution(
bytes memory resolution = appRegistry.getResolution(
appIdentityHash
);

require(
Transfer.meetsTerms(txn, terms),
"Transfer details do not meet terms"
);

txn.execute();
bytes memory payload = abi.encodeWithSignature("interpret(bytes,bytes)", resolution, interpreterParams);
(bool success, bytes memory returnData) = interpreterAddress.delegatecall(payload);
require(success);
}


Expand Down
29 changes: 8 additions & 21 deletions packages/contracts/contracts/default-apps/ETHBucket.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,23 @@ import "../CounterfactualApp.sol";

contract ETHBucket is CounterfactualApp {

struct ETHTransfer {
address to;
uint256 amount;
}

struct AppState {
address alice;
address bob;
uint256 aliceBalance;
uint256 bobBalance;
ETHTransfer[] transfers;
}

function resolve(bytes memory encodedState, Transfer.Terms memory terms)
public
pure
returns (Transfer.Transaction memory)
returns (bytes memory)
{
AppState memory state = abi.decode(encodedState, (AppState));

uint256[] memory amounts = new uint256[](2);
amounts[0] = state.aliceBalance;
amounts[1] = state.bobBalance;

address[] memory to = new address[](2);
to[0] = state.alice;
to[1] = state.bob;
bytes[] memory data = new bytes[](2);

return Transfer.Transaction(
terms.assetType,
terms.token,
to,
amounts,
data
);
return abi.encode(state.transfers);
}

function isStateTerminal(bytes memory)
Expand Down
Loading

0 comments on commit 51c45e5

Please sign in to comment.