// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; import {Script, console} from "forge-std/Script.sol"; import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import {MarketRegistry} from "../src/MarketRegistry.sol"; import {RiskVault} from "../src/RiskVault.sol"; import {FeeSplitter} from "../src/FeeSplitter.sol"; import {RiskEngine, IRandomnessProvider} from "../src/RiskEngine.sol"; import {VRFAdapter, IRiskEngineCallback} from "../src/VRFAdapter.sol"; /// Deploy to Arbitrum Sepolia (testnet). /// env: PRIVATE_KEY, USDC (mock or canonical), VRF_COORDINATOR, VRF_KEY_HASH, VRF_SUB_ID /// run: forge script script/Deploy.s.sol --rpc-url $ARB_SEPOLIA_RPC --broadcast --verify contract Deploy is Script { // Arbitrum Sepolia Chainlink VRF v2.5 defaults address constant DEFAULT_COORDINATOR = 0x5CE8D5A2BC84beb22a398CCA51996F7930313D61; bytes32 constant DEFAULT_KEY_HASH = 0x1770bdc7eec7771f7ba4ffd640f34260d7f095b79c92d34a5b2551d6f6cfd2be; function run() external { uint256 pk = vm.envUint("PRIVATE_KEY"); address deployer = vm.addr(pk); address usdc = vm.envAddress("USDC"); address coordinator = vm.envOr("VRF_COORDINATOR", DEFAULT_COORDINATOR); bytes32 keyHash = vm.envOr("VRF_KEY_HASH", DEFAULT_KEY_HASH); uint256 subId = vm.envUint("VRF_SUB_ID"); uint256 tvlCap = vm.envOr("TVL_CAP", uint256(300_000_000e6)); vm.startBroadcast(pk); MarketRegistry registry = new MarketRegistry(deployer); RiskVault vault = new RiskVault(IERC20(usdc), deployer, tvlCap); // burn sink / rebate pool / anchor reserve: deployer-controlled at testnet stage FeeSplitter splitter = new FeeSplitter(IERC20(usdc), deployer, deployer, deployer, deployer); VRFAdapter vrf = new VRFAdapter(coordinator, keyHash, subId, deployer); RiskEngine engine = new RiskEngine(registry, vault, splitter, IRandomnessProvider(address(vrf)), deployer); vault.setEngine(address(engine)); splitter.setEngine(address(engine)); vrf.setEngine(IRiskEngineCallback(address(engine))); // canonical launch markets (Track A archetypes) _listLaunchMarkets(registry); vm.stopBroadcast(); console.log("MarketRegistry:", address(registry)); console.log("RiskVault: ", address(vault)); console.log("FeeSplitter: ", address(splitter)); console.log("VRFAdapter: ", address(vrf)); console.log("RiskEngine: ", address(engine)); console.log("NOTE: add VRFAdapter as consumer to sub", subId); } function _listLaunchMarkets(MarketRegistry r) internal { // 1) binary even-money: p=0.5 @ 1.975x (EV .9875) _list2(r, 500_000, 1_975_000); // 2) uniform 4x-equivalent: p=0.246875 @ 4x (EV .9875) _list2(r, 246_875, 4_000_000); // 3) uniform 10x-equivalent: p=0.098750 @ 10x _list2(r, 98_750, 10_000_000); // 4) single-outcome 1/37 @ 36.5375x (EV .98750) _list2(r, 27_027, 36_537_500); // 5) long shot 1/101 @ 99.7375x ≈ 100x (EV .98750) _list2(r, 9_901, 99_737_500); } function _list2(MarketRegistry r, uint32 winP, uint64 payoutX) internal { uint32[] memory p = new uint32[](2); uint64[] memory x = new uint64[](2); p[0] = winP; x[0] = payoutX; p[1] = 1_000_000 - winP; x[1] = 0; r.listMarket(p, x); } }