Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
metalogica committed Nov 10, 2024
1 parent 30dedbc commit f489b8f
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 21 deletions.
61 changes: 54 additions & 7 deletions script/LMSR.s.sol
Original file line number Diff line number Diff line change
@@ -1,19 +1,66 @@
// script/DeployLMSR.s.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
pragma solidity ^0.8.19;

import {Script, console} from "forge-std/Script.sol";
import {Counter} from "../src/Counter.sol";
import {LMSRMarket} from "../src/LMSR.sol";
import {MockERC20} from "../test/ERC20.m.sol";

contract CounterScript is Script {
Counter public counter;
contract DeployLMSR is Script {
LMSRMarket public market;
MockERC20 public usdc;

function setUp() public {}
// Configuration
uint256 constant LIQUIDITY = 1000e18; // Initial liquidity parameter
uint256 constant NUM_OUTCOMES = 2; // Number of outcomes in the market

function setUp() public {
// Any setup configuration can go here
}

function run() public {
vm.startBroadcast();
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);

// For local testing, deploy a mock USDC
// For mainnet, you'd use the real USDC address
if (block.chainid == 31337) {
// Local anvil chain
usdc = new MockERC20("USDC", "USDC", 6);
console.log("Deployed Mock USDC at:", address(usdc));

// Mint some initial USDC for testing
usdc.mint(msg.sender, 1000000e6); // 1M USDC
}

counter = new Counter();
// Deploy LMSR Market
market = new LMSRMarket(
block.chainid == 31337 ? address(usdc) : getUSDCAddress(),
LIQUIDITY,
NUM_OUTCOMES
);

console.log("Deployed LMSR Market at:", address(market));
console.log("USDC address:", address(market.USDC()));
console.log("Number of outcomes:", market.numOutcomes());
console.log("Liquidity parameter:", market.liquidity());

vm.stopBroadcast();
}

function getUSDCAddress() internal view returns (address) {
// Return appropriate USDC address for different networks
if (block.chainid == 1) {
// Ethereum Mainnet USDC
return 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
} else if (block.chainid == 137) {
// Polygon Mainnet USDC
return 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174;
} else if (block.chainid == 42161) {
// Arbitrum USDC
return 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8;
} else {
revert("Unsupported network for USDC");
}
}
}
49 changes: 49 additions & 0 deletions test/ERC20.m.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {ERC20} from "@openzeppelin/token/ERC20/ERC20.sol";

contract MockERC20 is ERC20 {
uint8 private _decimals;

mapping(address => bool) public blocked;
bool public transferShouldRevert;
bool public mintShouldRevert;

constructor(
string memory name,
string memory symbol,
uint8 decimals_
) ERC20(name, symbol) {
_decimals = decimals_;
}

function mint(address to, uint256 amount) public {
require(!mintShouldRevert, "MINT_REVERTED");
_mint(to, amount);
}

function burn(address from, uint256 amount) public {
_burn(from, amount);
}

function decimals() public view override returns (uint8) {
return _decimals;
}

function blockAddress(address user) external {
blocked[user] = true;
}

function unblockAddress(address user) external {
blocked[user] = false;
}

function setTransferShouldRevert(bool shouldRevert) external {
transferShouldRevert = shouldRevert;
}

function setMintShouldRevert(bool shouldRevert) external {
mintShouldRevert = shouldRevert;
}
}
105 changes: 91 additions & 14 deletions test/LMSR.t.sol
Original file line number Diff line number Diff line change
@@ -1,24 +1,101 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
// test/LMSRMarket.t.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {Test, console} from "forge-std/Test.sol";
import {Counter} from "../src/Counter.sol";
import "forge-std/Test.sol";
import "../src/LMSR.sol";
import {MockERC20} from "./ERC20.m.sol";

contract CounterTest is Test {
Counter public counter;
contract LMSRMarketTest is Test {
LMSRMarket public market;
MockERC20 public usdc;

address alice = address(0x1);
address bob = address(0x2);

uint256 constant INITIAL_BALANCE = 1000000e6; // 1M USDC
uint256 constant LIQUIDITY = 1000e18;
uint256 constant NUM_OUTCOMES = 2;

function setUp() public {
counter = new Counter();
counter.setNumber(0);
// Deploy mock USDC
usdc = new MockERC20("USDC", "USDC", 6);

// Deploy market
market = new LMSRMarket(address(usdc), LIQUIDITY, NUM_OUTCOMES);

// Setup test accounts
vm.startPrank(alice);
usdc.mint(alice, INITIAL_BALANCE);
usdc.approve(address(market), type(uint256).max);
vm.stopPrank();

vm.startPrank(bob);
usdc.mint(bob, INITIAL_BALANCE);
usdc.approve(address(market), type(uint256).max);
vm.stopPrank();
}

function test_Increment() public {
counter.increment();
assertEq(counter.number(), 1);
function test_InitialState() public {
assertEq(market.numOutcomes(), NUM_OUTCOMES);
assertEq(market.liquidity(), LIQUIDITY);
assertEq(address(market.USDC()), address(usdc));
assertEq(market.resolved(), false);
}

function test_BuyShares() public {
vm.startPrank(alice);

uint256 amount = 100e6; // 100 USDC worth
uint256 outcome = 0;

uint256 cost = market.calculateCost(outcome, amount);
uint256 balanceBefore = usdc.balanceOf(alice);

market.buyShares(outcome, amount);

assertEq(usdc.balanceOf(alice), balanceBefore - cost);
assertEq(market.getUserPosition(alice, outcome), amount);
assertEq(market.quantities(outcome), amount);
}

function testFuzz_SetNumber(uint256 x) public {
counter.setNumber(x);
assertEq(counter.number(), x);
function test_RevertWhenBuyingAfterResolution() public {
// Resolve market first
market.resolveMarket(0);

vm.startPrank(alice);
vm.expectRevert(MarketAlreadyResolved.selector);
market.buyShares(0, 100e6);
}

function test_ClaimWinnings() public {
uint256 amount = 100e6;
uint256 outcome = 0;

// Buy shares
vm.startPrank(alice);
market.buyShares(outcome, amount);

// Resolve market
vm.stopPrank();
market.resolveMarket(outcome);

// Claim winnings
vm.startPrank(alice);
uint256 balanceBefore = usdc.balanceOf(alice);
market.claimWinnings(amount);

uint256 expectedPayout = (amount * market.SCALE()) /
(10 ** (18 - market.USDC_DECIMALS()));
assertEq(usdc.balanceOf(alice), balanceBefore + expectedPayout);
assertEq(market.getUserPosition(alice, outcome), 0);
}

function test_RevertWhenClaimingBeforeResolution() public {
vm.startPrank(alice);
market.buyShares(0, 100e6);

vm.expectRevert(MarketNotResolved.selector);
market.claimWinnings(100e6);
}
}

0 comments on commit f489b8f

Please sign in to comment.