From e381ab5ef6dbd1ebdb02200bc86bdefe4914c188 Mon Sep 17 00:00:00 2001 From: mike Date: Wed, 1 Nov 2023 15:53:50 -0700 Subject: [PATCH] add custom NegRiskCtfExchange --- .gitignore | 2 ++ .gitmodules | 3 ++ foundry.toml | 1 - lib/ctf-exchange | 1 + remappings.txt | 2 ++ src/NegRiskAdapter.sol | 26 ++++++++++++++++++ src/NegRiskCtfExchange.sol | 13 +++++++++ src/dev/libraries/DeployLib.sol | 14 ++++++++++ src/interfaces/INegRiskAdapter.sol | 44 ++++++++++++++++++++++++++++++ src/modules/MarketDataManager.sol | 2 +- 10 files changed, 106 insertions(+), 2 deletions(-) create mode 160000 lib/ctf-exchange create mode 100644 src/NegRiskCtfExchange.sol create mode 100644 src/interfaces/INegRiskAdapter.sol diff --git a/.gitignore b/.gitignore index e38c54b..82356d7 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ docs/ # python virtualenv env/ + +node_modules/ diff --git a/.gitmodules b/.gitmodules index b30cd81..0dede8f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "lib/forge-gas-snapshot"] path = lib/forge-gas-snapshot url = https://github.com/marktoda/forge-gas-snapshot +[submodule "lib/ctf-exchange"] + path = lib/ctf-exchange + url = https://github.com/Polymarket/ctf-exchange diff --git a/foundry.toml b/foundry.toml index 30d5add..2ebf860 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,5 +1,4 @@ [profile.default] -solc = "0.8.19" src = "src" out = "out" libs = ["lib"] diff --git a/lib/ctf-exchange b/lib/ctf-exchange new file mode 160000 index 0000000..503c0af --- /dev/null +++ b/lib/ctf-exchange @@ -0,0 +1 @@ +Subproject commit 503c0af02f9199177227f69ffcd5a7e4ca7b5d47 diff --git a/remappings.txt b/remappings.txt index 88db1e1..e3311f9 100644 --- a/remappings.txt +++ b/remappings.txt @@ -2,3 +2,5 @@ ds-test/=lib/forge-std/lib/ds-test/src/ forge-std/=lib/forge-std/src/ solmate/=lib/solmate/src/ forge-gas-snapshot/=lib/forge-gas-snapshot/src/ + +openzeppelin-contracts/=lib/ctf-exchange/lib/openzeppelin-contracts/contracts/ \ No newline at end of file diff --git a/src/NegRiskAdapter.sol b/src/NegRiskAdapter.sol index 6d54981..afe4bd7 100644 --- a/src/NegRiskAdapter.sol +++ b/src/NegRiskAdapter.sol @@ -164,6 +164,32 @@ contract NegRiskAdapter is ERC1155TokenReceiver, MarketStateManager, INegRiskAda emit PositionsMerge(msg.sender, _conditionId, _amount); } + /*////////////////////////////////////////////////////////////// + ERC1155 + //////////////////////////////////////////////////////////////*/ + + function balanceOf(address _owner, uint256 _id) external view returns (uint256) { + return ctf.balanceOf(_owner, _id); + } + + function balanceOfBatch(address[] memory _owners, uint256[] memory _ids) external view returns (uint256[] memory) { + return ctf.balanceOfBatch(_owners, _ids); + } + + function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external { + return ctf.safeTransferFrom(_from, _to, _id, _value, _data); + } + + function safeBatchTransferFrom( + address _from, + address _to, + uint256[] calldata _ids, + uint256[] calldata _values, + bytes calldata _data + ) external { + return ctf.safeBatchTransferFrom(_from, _to, _ids, _values, _data); + } + /*////////////////////////////////////////////////////////////// REDEEM POSITION //////////////////////////////////////////////////////////////*/ diff --git a/src/NegRiskCtfExchange.sol b/src/NegRiskCtfExchange.sol new file mode 100644 index 0000000..e0716aa --- /dev/null +++ b/src/NegRiskCtfExchange.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {CTFExchange} from "lib/ctf-exchange/src/exchange/CTFExchange.sol"; +import {ERC1155} from "lib/solmate/src/tokens/ERC1155.sol"; + +contract NegRiskCtfExchange is CTFExchange { + constructor(address _collateral, address _negRiskAdapter, address _ctf, address _proxyFactory, address _safeFactory) + CTFExchange(_collateral, _negRiskAdapter, _proxyFactory, _safeFactory) + { + ERC1155(_ctf).setApprovalForAll(_negRiskAdapter, true); + } +} diff --git a/src/dev/libraries/DeployLib.sol b/src/dev/libraries/DeployLib.sol index e9f1330..1891108 100644 --- a/src/dev/libraries/DeployLib.sol +++ b/src/dev/libraries/DeployLib.sol @@ -26,4 +26,18 @@ library DeployLib { vm.label(deployment, "UmaCtfAdapter"); return deployment; } + + function deployNegRiskCtfExchange( + address _collateral, + address _negRiskAdapter, + address _ctf, + address _proxyFactory, + address _safeFactory + ) public returns (address) { + address deployment = _deployCode( + "artifacts/UmaCtfAdapter.json", abi.encode(_collateral, _negRiskAdapter, _ctf, _proxyFactory, _safeFactory) + ); + vm.label(deployment, "UmaCtfAdapter"); + return deployment; + } } diff --git a/src/interfaces/INegRiskAdapter.sol b/src/interfaces/INegRiskAdapter.sol new file mode 100644 index 0000000..742a08a --- /dev/null +++ b/src/interfaces/INegRiskAdapter.sol @@ -0,0 +1,44 @@ +pragma solidity ^0.8.10; + +interface Interface { + event MarketPrepared(bytes32 indexed marketId, address indexed oracle, uint256 feeBips, bytes data); + event OutcomeReported(bytes32 indexed marketId, bytes32 indexed questionId, bool outcome); + event PayoutRedemption(address indexed redeemer, bytes32 indexed conditionId, uint256[] amounts, uint256 payout); + event PositionSplit(address indexed stakeholder, bytes32 indexed conditionId, uint256 amount); + event PositionsConverted( + address indexed stakeholder, bytes32 indexed marketId, uint256 indexed indexSet, uint256 amount + ); + event PositionsMerge(address indexed stakeholder, bytes32 indexed conditionId, uint256 amount); + event QuestionPrepared(bytes32 indexed marketId, bytes32 indexed questionId, uint256 index, bytes data); + + function FEE_DENOMINATOR() external view returns (uint256); + function NO_TOKEN_BURN_ADDRESS() external view returns (address); + function col() external view returns (address); + function convertPositions(bytes32 _marketId, uint256 _indexSet, uint256 _amount) external; + function ctf() external view returns (address); + function getConditionId(bytes32 _questionId) external view returns (bytes32); + function getDetermined(bytes32 _marketId) external view returns (bool); + function getFeeBips(bytes32 _marketId) external view returns (uint256); + function getMarketData(bytes32 _marketId) external view returns (bytes32); + function getOracle(bytes32 _marketId) external view returns (address); + function getPositionId(bytes32 _questionId, bool _outcome) external view returns (uint256); + function getQuestionCount(bytes32 _marketId) external view returns (uint256); + function getResult(bytes32 _marketId) external view returns (uint256); + function mergePositions(address _collateralToken, bytes32, bytes32 _conditionId, uint256[] memory, uint256 _amount) + external; + function mergePositions(bytes32 _conditionId, uint256 _amount) external; + function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) + external + returns (bytes4); + function onERC1155Received(address, address, uint256, uint256, bytes memory) external returns (bytes4); + function prepareMarket(uint256 _feeBips, bytes memory _metadata) external returns (bytes32); + function prepareQuestion(bytes32 _marketId, bytes memory _metadata) external returns (bytes32); + function redeemPositions(bytes32 _conditionId, uint256[] memory _amounts) external; + function reportOutcome(bytes32 _questionId, bool _outcome) external; + function splitPosition(address _collateralToken, bytes32, bytes32 _conditionId, uint256[] memory, uint256 _amount) + external; + function splitPosition(bytes32 _conditionId, uint256 _amount) external; + function vault() external view returns (address); + function wcol() external view returns (address); +} + diff --git a/src/modules/MarketDataManager.sol b/src/modules/MarketDataManager.sol index 556aa2b..696bab6 100644 --- a/src/modules/MarketDataManager.sol +++ b/src/modules/MarketDataManager.sol @@ -17,7 +17,7 @@ interface IMarketStateManagerEE { /// @notice Manages market state on behalf of the NegRiskAdapter /// @author Mike Shrieve(mike@polymarket.com) abstract contract MarketStateManager is IMarketStateManagerEE { - mapping(bytes32 _marketId => MarketData) internal marketData; + mapping(bytes32 => MarketData) internal marketData; /*////////////////////////////////////////////////////////////// GETTERS