-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
30dedbc
commit f489b8f
Showing
3 changed files
with
194 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |