Create Conditional Tokens Positions on Gnosis Chain using Scaffold-Eth 2.
This document uses the Gnosis documentation “Introduction - Gnosis Developer Portal Conditional Tokens” as its source and will cover a limited Scope of the tutorial.
Repositories and Modifications
Deploy Conditional and Collateral Token Contracts
Mint and Approve Collateral Tokens
Conditional Token Preparation
Creating Positions with Conditional Tokens
The contract code was copied from the Gist repository in the gnosis tutorial and modified to support integration into scaffold-eth.
gnostic-condition branch on OwlWilderness/se-2 repository
This is the working repository for code in this demo.
The import format was modified to use @Openzepplin instead of a github reference in all files.
SafeMath was included for uint in the Conditional Tokens contract.
//SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;
import { SafeMath } from "@openzeppelin/contracts/utils/math/SafeMath.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { ERC1155 } from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import { CTHelpers } from "./CTHelpers.sol";
// Mainnet (ID: 1) canonical address: 0xC59b0e4De5F1248C1140964E0fF287B192407E0C
// Rinkeby (ID: 4) canonical address: 0x36bede640D19981A82090519bC1626249984c908
contract ConditionalTokens is ERC1155 {
using SafeMath for uint;
...
String Utilities were added to the CT Helper Contract to support a method to return the position ID as a string
**the scaffold eth debug contract getPositionId(…) returns the uint as floating point eth
example:
Ξ30538692964205559938227141519166067798763549412261626800343.848901573363871063
//SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
...
function getStringPositionId(IERC20 collateralToken, bytes32 collectionId) internal pure returns (string memory) {
return Strings.toString(uint(keccak256(abi.encodePacked(collateralToken, collectionId))));
}
The Gist repository provides one contract to execute and mint multiple collateral tokens using different name and symbol.
Two contracts are created and deployed in scaffold-eth as the deployed contract object uses the name of the contract as the key.
**without doing this OOB the debug contract page will only show for one of the collateral tokens
//SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;
import { ConditionalTokens } from "./ConditionalTokens.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract GnosticToken0 is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {}
function mint(address account, uint256 amount) external {
_mint(account, amount);
}
}
contract GnosticToken1 is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {}
function mint(address account, uint256 amount) external {
_mint(account, amount);
}
}
Fork / clone the gnostic-condition repository - reference the below article for instruction.
Follow instructions in Scaffold-eth 2 ReadMe to Yarn Install, Chain, Start and Deploy to start the hardhat chain local webhost
Open a new private window and navigate to http://localhost:3000/debug
Click the Faucet Icon in the upper right to fund the hardhat wallet.
Collateral Tokens are used to Mint Conditional Position Tokens. In this example we will mint two Collateral Tokens Gnostic Token 0 (GT0) and Gnostic Token 1 (GT1).
Click the Address in the upper right to open the menu and Click Copy Address
Click the Debug Gnostic Contracts Tab then → the GnosticToken0 tab.
Scroll to the Mint Token section
Paste the copied wallet address into the address account field and enter 1000 into the uint256 amount field.
Click Send
Note Supply of GT0 increased to 1000
Note the GnosticToken0 address by clicking the copy icon
Navigate to Gnostic Token 1
Repeat Process to Mint Gnostic Token 1 - Scroll to Mint Area- Paste Copied Wallet Address into address account field- Enter 1000 into uint256 amount field- Copy / Note the GnosticToken1 address
Navigate to ConditionalTokens Debug Contract and Copy Address
Navigate to GnosticToken0 Approve Section
Paste copied address into the address spender field.
Enter 1000 into the amount field
Click Send
Repeat Process for Gnostic Token 1
record addresses, values and hashes. these values will change after each deployment and are for illustration purposes only.
Hardhat Wallet Address : 0x0a3b031cC1234315a92E647889F9182BC061E8A0
Conditional Token Address : 0x5FbDB2315678afecb367f032d93F642f64180aa3
Gnostic Token 0 (GT0) : 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
Gnostic Token 1 (GT1) : 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0
Parent Collection : 0x0000000000000000000000000000000000000000000000000000000000000000
Question ID 1 : 0x0000000000000000000000000000000000000000000000000000000000000001
Question ID 2 : 0x0000000000000000000000000000000000000000000000000000000000000002
Oracle : ETH ADDRESS
Question ID : ANY 32 BYTES of HEX
Number of Possible Outcomes : BETWEEN 2-256 POSSIBLE OUTCOMES
getConditionId Question 1: 0xa9620c3b3514f4c96c9f53642913021e2ed08eb083748b5f615dc5f3c80b7000
Oracle : 0x0a3b031cC1234315a92E647889F9182BC061E8A0
Question ID 1 : 0x0000000000000000000000000000000000000000000000000000000000000001
# Outcomes: 3
getConditionId Question 2: 0x15d6a8d1501917bb78d09b863412bf66b9c9e2f5f1f624af75531406f454e7bb
Oracle : 0x0a3b031cC1234315a92E647889F9182BC061E8A0
Question ID 2 : 0x0000000000000000000000000000000000000000000000000000000000000002
# Outcomes: 2
Collection - Outcome B|C for Question 1 : 0x0f7deef25c034a8752aea625d5a7e2fe3fad44e9633026dd92688252a76be7f1
Parent ID: 0x0000000000000000000000000000000000000000000000000000000000000000
Condition ID Question 1 : 0xa9620c3b3514f4c96c9f53642913021e2ed08eb083748b5f615dc5f3c80b7000
Index Set: 6 = 0b110 = Outcome (B|C)
Collection - Outcome A for Question 1: 0x1e4d7015a719ca11166cac05af32305e31a207fc15e6549aaee014f4e54d1c32
Parent ID: 0x0000000000000000000000000000000000000000000000000000000000000000
Condition ID Question 1 : 0xa9620c3b3514f4c96c9f53642913021e2ed08eb083748b5f615dc5f3c80b7000
Index Set: 1 = 0b001 = Outcome A
Collection - Outcome Low for Question 2: 0x4f3e685bd90b864855a543862c9a5ccfdd004e0ed41966810e3421ef0352733d
Parent ID: 0x0000000000000000000000000000000000000000000000000000000000000000
Condition ID Question 1 : 0x15d6a8d1501917bb78d09b863412bf66b9c9e2f5f1f624af75531406f454e7bb
Index Set: 1 = 0b01 = Outcome Low
Collection - Outcome Hi for Question 2: 0x4872a0885cbc2f9edb8ced8e5edb54349ee133a96ac996e94a003b0cde443ff6
Parent ID: 0x0000000000000000000000000000000000000000000000000000000000000000
Condition ID Question 1 : 0x15d6a8d1501917bb78d09b863412bf66b9c9e2f5f1f624af75531406f454e7bb
Index Set: 2 = 0b10 = Outcome Hi
Collections:
Collection - Outcome B|C for Question 1 : 0x0f7deef25c034a8752aea625d5a7e2fe3fad44e9633026dd92688252a76be7f1
Collection - Outcome A for Question 1: 0x1e4d7015a719ca11166cac05af32305e31a207fc15e6549aaee014f4e54d1c32
Collection - Outcome Low for Question 2: 0x4f3e685bd90b864855a543862c9a5ccfdd004e0ed41966810e3421ef0352733d
Collection - Outcome Hi for Question 2: 0x4872a0885cbc2f9edb8ced8e5edb54349ee133a96ac996e94a003b0cde443ff6
Tokens
Gnostic Token 0 (GT0) : 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
Gnostic Token 1 (GT1) : 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0
Position GT0-1 B|C : 69756881759866133805660629677137340800784931395161768631268343007553287298947
Position GT0-1 A : 82731255938747274424991476311812858093949303227342239819305777831695159296885
Position GT1-1 B|C : 39907225118877227855298033650136733790066605943132640619358681018232170696662
Position GT1-1 A : 71119352066877664618372522921430707264363198477866865446318236169980389097443
Position GT0-2 Low : 33407020960471868732595667962325811837077945823734802324599614554532694637363
Position GT0-2 Hi : 111110653929981865175832810059537209326101375996587576828500820462032281170479
Position GT1-2 Low : 22624642637007454965289107974225720027671607220739183332440370573482761255543
Position GT1-2 Hi: 26320361178311307871541764768252101128993509163924835565533731277595907344887
Create Positions with the Collateral Tokens
GT0 Question 1 Position
address collateral token : Gnostic Token 0 (GT0) : 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
bytes32 parentCollectionId : 0x0000000000000000000000000000000000000000000000000000000000000000
bytes32 conditionId : ConditionId Question 1: 0xa9620c3b3514f4c96c9f53642913021e2ed08eb083748b5f615dc5f3c80b7000
uint256 partitions : [1,6] = [0b001 = Outcome A, 0b110 = Outcome 6]
uint256 amount : 100
GT1 Question 1 Position
address collateral token : Gnostic Token 0 (GT1) : 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0
bytes32 parentCollectionId : 0x0000000000000000000000000000000000000000000000000000000000000000
bytes32 conditionId : ConditionId Question 1: 0xa9620c3b3514f4c96c9f53642913021e2ed08eb083748b5f615dc5f3c80b7000
uint256 partitions : [1,6] = [0b001 = Outcome A, 0b110 = Outcome 6]
uint256 amount : 100
GT0 Question 2 Position
address collateral token : Gnostic Token 0 (GT0) : 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
bytes32 parentCollectionId : 0x0000000000000000000000000000000000000000000000000000000000000000
bytes32 conditionId : ConditionId Question 1: 0x15d6a8d1501917bb78d09b863412bf66b9c9e2f5f1f624af75531406f454e7bb
uint256 partitions : [1,2] = [0b01 = Low, 0b10 = Hi]
uint256 amount : 100
GT1 Question 2 Position
address collateral token : Gnostic Token 0 (GT1) : 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0
bytes32 parentCollectionId : 0x0000000000000000000000000000000000000000000000000000000000000000
bytes32 conditionId : ConditionId Question 1: 0x15d6a8d1501917bb78d09b863412bf66b9c9e2f5f1f624af75531406f454e7bb
uint256 partitions : [1,2] = [0b01 = Low, 0b10 = Hi]
uint256 amount : 100
Use Balance Of and Position ID to read back positions:
Enter Wallet Address in address account field
Enter Position ID in uint256 id field