Skip to content

Commit

Permalink
wip: dispure test
Browse files Browse the repository at this point in the history
  • Loading branch information
pysel committed Nov 28, 2024
1 parent 4440251 commit 553794f
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/ClvrHook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ contract ClvrHook is BaseHook, ClvrStake, ClvrSlashing {
/// @param batchIndex The index of the batch to dispute
/// @param betterReordering The reordering of swaps that is better than the retained batch
function disputeBatch(PoolKey calldata key, uint256 batchIndex, uint256[] memory betterReordering) public {
require(batchIndex < ClvrSlashing.BATCH_RETENTION_PERIOD, "Batch index out of bounds");
require(!retainedBatches[key.toId()][batchIndex].disputed, "Batch already disputed");

bytes4 magic = _disputeBatch(key, batchIndex, betterReordering);
if (magic == ClvrSlashing.BATCH_DISPUTED_MAGIC_VALUE) {
payable(msg.sender).transfer(ClvrStake.STAKE_AMOUNT);
Expand Down
55 changes: 51 additions & 4 deletions src/ClvrModel.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,23 @@ contract ClvrModel {
public
equalLength(challengedOrdering, candidateOrdering)
returns (bool)
{
{
set_reserve_x(reserve_x);
set_reserve_y(reserve_y);

challengedOrdering = addMockTrade(challengedOrdering);
candidateOrdering = addMockTrade(candidateOrdering);

int128 lnP0 = p0.lnU256().toInt128();
int256 lnP0 = p0.lnU256().toInt256();
for (uint256 i = 1; i < challengedOrdering.length; i++) {
int128 unsquaredChallengedValue = lnP0 - P(challengedOrdering, i).lnU256().toInt128();
int256 unsquaredChallengedValue = lnP0 - P(challengedOrdering, i).lnU256().toInt256();
int256 challengedValue = unsquaredChallengedValue ** 2 / 1e18;
// console.log(P(challengedOrdering, i), P(candidateOrdering, i));
console.log(challengedOrdering[i].params.zeroForOne ? "buy" : "sell", challengedOrdering[i].params.amountSpecified);
console.log(candidateOrdering[i].params.zeroForOne ? "buy" : "sell", candidateOrdering[i].params.amountSpecified);


int128 unsquaredCandidateValue = lnP0 - P(candidateOrdering, i).lnU256().toInt128();
int256 unsquaredCandidateValue = lnP0 - P(candidateOrdering, i).lnU256().toInt256();
int256 candidateValue = unsquaredCandidateValue ** 2 / 1e18;

// the candidate ordering is better because the value is lower
Expand Down Expand Up @@ -148,6 +152,49 @@ contract ClvrModel {
revert("Invalid call to X");
}

function y_out_cached(ClvrHook.SwapParamsExtended[] memory o, uint256 i, uint256 cachedY, uint256 cachedX) private pure returns (uint256) {
if (direction(o[i]) == Direction.Sell) {
uint256 fraction = cachedY / (cachedX + amountIn(o[i]));
return fraction * amountIn(o[i]);
}

return 0;
}

function x_out_cached(ClvrHook.SwapParamsExtended[] memory o, uint256 i, uint256 cachedY, uint256 cachedX) private pure returns (uint256) {
if (direction(o[i]) == Direction.Buy) {
uint256 fraction = cachedX / (cachedY + amountIn(o[i]));
return fraction * amountIn(o[i]);
}
return 0;
}

function Y_cached(ClvrHook.SwapParamsExtended[] memory o, uint256 i, uint256 cachedY, uint256 cachedX) private view returns (uint256) {
if (i == 0) {
return reserveY;
} else if (i > 0 && direction(o[i]) == Direction.Buy) {
return cachedY + amountIn(o[i]);
} else if (i > 0 && direction(o[i]) == Direction.Sell) {
return cachedY - y_out_cached(o, i, cachedY, cachedX);
}
revert("Invalid call to Y_cached");
}

function X_cached(ClvrHook.SwapParamsExtended[] memory o, uint256 i, uint256 cachedY, uint256 cachedX) private view returns (uint256) {
if (i == 0) {
return reserveX;
} else if (i > 0 && direction(o[i]) == Direction.Sell) {
return cachedX + amountIn(o[i]);
} else if (i > 0 && direction(o[i]) == Direction.Buy) {
return cachedX - x_out_cached(o, i, cachedY, cachedX);
}
revert("Invalid call to X_cached");
}

function P_cached(ClvrHook.SwapParamsExtended[] memory o, uint256 i, uint256 cachedY, uint256 cachedX) private view returns (uint256) {
return Y_cached(o, i, cachedY, cachedX) * 1e18 / X_cached(o, i, cachedY, cachedX);
}

function direction(ClvrHook.SwapParamsExtended memory o) private pure returns (Direction) {
if (o.recepient == address(0)) {
return Direction.NULL;
Expand Down
30 changes: 30 additions & 0 deletions test/ClvrHook.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,36 @@ contract ClvrHookTest is Test, Deployers, Fixtures {
vm.stopPrank();
}

function testDisputeBatch() public {
dealCurrencyToUsers();
approveSwapRouter();
approveHook();
stakeScheduler();

sendSwaps();

uint256[] memory badOrdering = new uint256[](USERS_LENGTH);

// execute even-indexed swaps first (sell direction), then odd-indexed swaps (buy direction)
for (uint256 i = 0; i < USERS_LENGTH/2; i++) {
badOrdering[i] = 2 * i;
}

for (uint256 i = USERS_LENGTH/2; i < USERS_LENGTH; i++) {
badOrdering[i] = 2 * (i - USERS_LENGTH/2) + 1;
}

executeBatch(abi.encode(badOrdering));

uint256[] memory betterOrdering = getSwapIds();

address disputer = makeAddr("Disputer");

vm.startPrank(disputer, disputer);
hook.disputeBatch(key, hook.BATCH_RETENTION_PERIOD() - 1, betterOrdering);
vm.stopPrank();
}

// UTILITY FUNCTIONS

function stakeScheduler() internal {
Expand Down

0 comments on commit 553794f

Please sign in to comment.