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

Commit

Permalink
Revert "Merge branch 'develop' into 2022-08-26-emissions-mores-stuff"
Browse files Browse the repository at this point in the history
This reverts commit 8d092ad, reversing
changes made to ee68505.
  • Loading branch information
marcusnewton committed Sep 1, 2022
1 parent 8d092ad commit c12b8d5
Show file tree
Hide file tree
Showing 187 changed files with 816 additions and 5,072 deletions.
2 changes: 1 addition & 1 deletion contracts/cooldown/Cooldown.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ contract Cooldown {
/// @param cooldownDuration_ The global cooldown duration.
function initializeCooldown(uint256 cooldownDuration_) internal {
require(cooldownDuration_ > 0, "COOLDOWN_0");
require(cooldownDuration_ <= type(uint32).max, "COOLDOWN_MAX");
require(cooldownDuration <= type(uint32).max, "COOLDOWN_MAX");
// Reinitialization is a bug.
assert(cooldownDuration == 0);
cooldownDuration = cooldownDuration_;
Expand Down
259 changes: 83 additions & 176 deletions contracts/orderbook/OrderBook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ struct WithdrawConfig {
}

struct ClearConfig {
uint256 aInputIOIndex;
uint256 aOutputIOIndex;
uint256 bInputIOIndex;
uint256 bOutputIOIndex;
uint256 aInputIndex;
uint256 aOutputIndex;
uint256 bInputIndex;
uint256 bOutputIndex;
uint256 aBountyVaultId;
uint256 bBountyVaultId;
}
Expand All @@ -47,21 +47,6 @@ struct ClearStateChange {
IdempotentFlag bFlag;
}

struct TakeOrderConfig {
Order order;
uint256 inputIOIndex;
uint256 outputIOIndex;
}

struct TakeOrdersConfig {
address output;
address input;
uint256 minimumInput;
uint256 maximumInput;
uint256 maximumIORatio;
TakeOrderConfig[] orders;
}

uint256 constant LOCAL_OPS_LENGTH = 2;

library LibEvalContext {
Expand Down Expand Up @@ -100,12 +85,6 @@ contract OrderBook is StandardVM {
event OrderDead(address sender, Order config);
event Clear(address sender, Order a_, Order b_, ClearConfig clearConfig);
event AfterClear(ClearStateChange stateChange);
event TakeOrder(
address sender,
TakeOrderConfig takeOrder,
uint256 input,
uint256 output
);

// order hash => order liveness
mapping(OrderHash => OrderLiveness) private orders;
Expand Down Expand Up @@ -179,117 +158,6 @@ contract OrderBook is StandardVM {
}
}

function _calculateOrderIO(
Order memory order_,
uint256 outputIOIndex_,
address counterparty_
) internal view returns (uint256 orderOutputMax_, uint256 orderIORatio_) {
VMState memory vmState_ = order_.vmState.deserialize(
EvalContext(order_.hash(), counterparty_).toContext()
);
(orderOutputMax_, orderIORatio_) = vmState_.eval().peek2();

// The order owner can't send more than the smaller of their vault
// balance or their per-order limit.
IO memory outputIO_ = order_.validOutputs[outputIOIndex_];
orderOutputMax_ = orderOutputMax_.min(
vaults[order_.owner][outputIO_.token][outputIO_.vaultId]
);
}

function _recordVaultIO(
Order memory order_,
address counterparty_,
uint256 inputIOIndex_,
uint256 input_,
uint256 outputIOIndex_,
uint256 output_
) internal {
IO memory io_;
if (input_ > 0) {
io_ = order_.validInputs[inputIOIndex_];
vaults[order_.owner][io_.token][io_.vaultId] += input_;
}
if (output_ > 0) {
io_ = order_.validOutputs[outputIOIndex_];
vaults[order_.owner][io_.token][io_.vaultId] -= output_;
if (_isTracked(order_.tracking, TRACKING_FLAG_CLEARED_ORDER)) {
clearedOrder[order_.hash()] += output_;
}
if (
_isTracked(order_.tracking, TRACKING_FLAG_CLEARED_COUNTERPARTY)
) {
clearedCounterparty[order_.hash()][counterparty_] += output_;
}
}
}

function takeOrders(TakeOrdersConfig calldata takeOrders_)
external
returns (uint256 totalInput_, uint256 totalOutput_)
{
uint256 i_ = 0;
TakeOrderConfig memory takeOrder_;
Order memory order_;
uint256 remainingInput_ = takeOrders_.maximumInput;
while (i_ < takeOrders_.orders.length && remainingInput_ > 0) {
takeOrder_ = takeOrders_.orders[i_];
order_ = takeOrder_.order;
require(
order_.validInputs[takeOrder_.inputIOIndex].token ==
takeOrders_.output,
"TOKEN_MISMATCH"
);
require(
order_.validOutputs[takeOrder_.outputIOIndex].token ==
takeOrders_.input,
"TOKEN_MISMATCH"
);

(
uint256 orderOutputMax_,
uint256 orderIORatio_
) = _calculateOrderIO(order_, takeOrder_.outputIOIndex, msg.sender);

// Skip orders that are too expensive rather than revert as we have
// no way of knowing if a specific order becomes too expensive
// between submitting to mempool and execution, but other orders may
// be valid so we want to take advantage of those if possible.
if (
orderIORatio_ <= takeOrders_.maximumIORatio &&
orderOutputMax_ > 0
) {
uint256 input_ = remainingInput_.min(orderOutputMax_);
uint256 output_ = input_.fixedPointMul(orderIORatio_);

remainingInput_ -= input_;
totalOutput_ += output_;

_recordVaultIO(
order_,
msg.sender,
takeOrder_.inputIOIndex,
output_,
takeOrder_.outputIOIndex,
input_
);
emit TakeOrder(msg.sender, takeOrder_, input_, output_);
}

unchecked {
i_++;
}
}
totalInput_ = takeOrders_.maximumInput - remainingInput_;
require(totalInput_ >= takeOrders_.minimumInput, "MIN_INPUT");
IERC20(takeOrders_.output).safeTransferFrom(
msg.sender,
address(this),
totalOutput_
);
IERC20(takeOrders_.input).safeTransfer(msg.sender, totalInput_);
}

function clear(
Order memory a_,
Order memory b_,
Expand All @@ -298,13 +166,13 @@ contract OrderBook is StandardVM {
{
require(a_.owner != b_.owner, "SAME_OWNER");
require(
a_.validOutputs[clearConfig_.aOutputIOIndex].token ==
b_.validInputs[clearConfig_.bInputIOIndex].token,
a_.validOutputs[clearConfig_.aOutputIndex].token ==
b_.validInputs[clearConfig_.bInputIndex].token,
"TOKEN_MISMATCH"
);
require(
b_.validOutputs[clearConfig_.bOutputIOIndex].token ==
a_.validInputs[clearConfig_.aInputIOIndex].token,
b_.validOutputs[clearConfig_.bOutputIndex].token ==
a_.validInputs[clearConfig_.aInputIndex].token,
"TOKEN_MISMATCH"
);
require(orders[a_.hash()].isLive(), "A_NOT_LIVE");
Expand All @@ -314,9 +182,9 @@ contract OrderBook is StandardVM {
ClearStateChange memory stateChange_;

{
// IORatio is input per output for both a_ and b_.
uint256 aIORatio_;
uint256 bIORatio_;
// Price is input per output for both a_ and b_.
uint256 aPrice_;
uint256 bPrice_;
// a_ and b_ can both set a maximum output from the VM.
uint256 aOutputMax_;
uint256 bOutputMax_;
Expand All @@ -325,63 +193,102 @@ contract OrderBook is StandardVM {
// VM execution in eval.
emit Clear(msg.sender, a_, b_, clearConfig_);

(aOutputMax_, aIORatio_) = _calculateOrderIO(
a_,
clearConfig_.aOutputIOIndex,
b_.owner
);
(bOutputMax_, bIORatio_) = _calculateOrderIO(
b_,
clearConfig_.bOutputIOIndex,
a_.owner
);
unchecked {
{
VMState memory state_ = a_.vmState.deserialize(
EvalContext(a_.hash(), b_.owner).toContext()
);
stateChange_.aFlag = IdempotentFlag.wrap(state_.scratch);
(aOutputMax_, aPrice_) = state_.eval().peek2();
}

{
VMState memory state_ = b_.vmState.deserialize(
EvalContext(b_.hash(), a_.owner).toContext()
);
stateChange_.bFlag = IdempotentFlag.wrap(state_.scratch);
(bOutputMax_, bPrice_) = state_.eval().peek2();
}
}

// outputs are capped by the remaining funds in their output vault.
{
aOutputMax_ = aOutputMax_.min(
vaults[a_.owner][
a_.validOutputs[clearConfig_.aOutputIndex].token
][a_.validOutputs[clearConfig_.aOutputIndex].vaultId]
);
bOutputMax_ = bOutputMax_.min(
vaults[b_.owner][
b_.validOutputs[clearConfig_.bOutputIndex].token
][b_.validOutputs[clearConfig_.bOutputIndex].vaultId]
);
}

stateChange_.aOutput = aOutputMax_.min(
bOutputMax_.fixedPointMul(bIORatio_)
bOutputMax_.fixedPointMul(bPrice_)
);
stateChange_.bOutput = bOutputMax_.min(
aOutputMax_.fixedPointMul(aIORatio_)
aOutputMax_.fixedPointMul(aPrice_)
);

require(
stateChange_.aOutput > 0 || stateChange_.bOutput > 0,
"0_CLEAR"
);

stateChange_.aInput = stateChange_.aOutput.fixedPointMul(aIORatio_);
stateChange_.bInput = stateChange_.bOutput.fixedPointMul(bIORatio_);
stateChange_.aInput = stateChange_.aOutput.fixedPointMul(aPrice_);
stateChange_.bInput = stateChange_.bOutput.fixedPointMul(bPrice_);
}

_recordVaultIO(
a_,
b_.owner,
clearConfig_.aInputIOIndex,
stateChange_.aInput,
clearConfig_.aOutputIOIndex,
stateChange_.aOutput
);
_recordVaultIO(
b_,
a_.owner,
clearConfig_.bInputIOIndex,
stateChange_.bInput,
clearConfig_.bOutputIOIndex,
stateChange_.bOutput
);

if (stateChange_.aOutput > 0) {
vaults[a_.owner][a_.validOutputs[clearConfig_.aOutputIndex].token][
a_.validOutputs[clearConfig_.aOutputIndex].vaultId
] -= stateChange_.aOutput;
if (stateChange_.aFlag.get(FLAG_INDEX_CLEARED_ORDER)) {
clearedOrder[a_.hash()] += stateChange_.aOutput;
}
if (stateChange_.aFlag.get(FLAG_INDEX_CLEARED_COUNTERPARTY)) {
// A counts funds paid to cover the bounty as cleared for B.
clearedCounterparty[a_.hash()][b_.owner] += stateChange_
.aOutput;
}
}
if (stateChange_.bOutput > 0) {
vaults[b_.owner][b_.validOutputs[clearConfig_.bOutputIndex].token][
b_.validOutputs[clearConfig_.bOutputIndex].vaultId
] -= stateChange_.bOutput;
if (stateChange_.bFlag.get(FLAG_INDEX_CLEARED_ORDER)) {
clearedOrder[b_.hash()] += stateChange_.bOutput;
}
if (stateChange_.bFlag.get(FLAG_INDEX_CLEARED_COUNTERPARTY)) {
clearedCounterparty[b_.hash()][a_.owner] += stateChange_
.bOutput;
}
}
if (stateChange_.aInput > 0) {
vaults[a_.owner][a_.validInputs[clearConfig_.aInputIndex].token][
a_.validInputs[clearConfig_.aInputIndex].vaultId
] += stateChange_.aInput;
}
if (stateChange_.bInput > 0) {
vaults[b_.owner][b_.validInputs[clearConfig_.bInputIndex].token][
b_.validInputs[clearConfig_.bInputIndex].vaultId
] += stateChange_.bInput;
}
{
// At least one of these will overflow due to negative bounties if
// there is a spread between the orders.
uint256 aBounty_ = stateChange_.aOutput - stateChange_.bInput;
uint256 bBounty_ = stateChange_.bOutput - stateChange_.aInput;
if (aBounty_ > 0) {
vaults[msg.sender][
a_.validOutputs[clearConfig_.aOutputIOIndex].token
a_.validOutputs[clearConfig_.aOutputIndex].token
][clearConfig_.aBountyVaultId] += aBounty_;
}
if (bBounty_ > 0) {
vaults[msg.sender][
b_.validOutputs[clearConfig_.bOutputIOIndex].token
b_.validOutputs[clearConfig_.bOutputIndex].token
][clearConfig_.bBountyVaultId] += bBounty_;
}
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/AllStandardOpsTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ contract AllStandardOpsTest is StandardVM {
uint256 a_ = gasleft();
StackTop stackTop_ = state_.eval();
uint256 b_ = gasleft();
console.log("eval gas", a_ - b_);
console.log("eval", a_ - b_);
// Never actually do this, state is gigantic so can't live in storage.
// This is just being done to make testing easier than trying to read
// results from events etc.
Expand Down
34 changes: 0 additions & 34 deletions contracts/test/wrappers/CooldownTest.sol

This file was deleted.

Loading

0 comments on commit c12b8d5

Please sign in to comment.