Create Gnostic Conditional Token Positions using Scaffold Eth
August 28th, 2023

Summary

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.

  • Gnosis Developer Portal Conditional Tokens Tutorial
  • Scaffold-Eth 2

Scope

  • Repositories and Modifications

  • Deploy Conditional and Collateral Token Contracts

  • Mint and Approve Collateral Tokens

  • Conditional Token Preparation

  • Creating Positions with Conditional Tokens

Repositories and Modifications

The contract code was copied from the Gist repository in the gnosis tutorial and modified to support integration into scaffold-eth.

Reference: Gnosis Developer Gist Repository

In Use: Gnostic Condition Scaffold Eth Repository

gnostic-condition branch on OwlWilderness/se-2 repository

This is the working repository for code in this demo.

Conditional Token Contract

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;

...

CT Helper Contract

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))));
}

Collateral Token Contracts

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);
    }
}

Deploy Conditional and Collateral Token Contracts

Fork and Clone gnostic-condition repository

Fork / clone the gnostic-condition repository - reference the below article for instruction.

Deploy Contracts On Hardhat

Follow instructions in Scaffold-eth 2 ReadMe to Yarn Install, Chain, Start and Deploy to start the hardhat chain local webhost

Fund Hardhat Wallet

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.

Mint and Approve Collateral Tokens

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).

Copy Wallet Address

Click the Address in the upper right to open the menu and Click Copy Address

Navigate to Gnostic Token 0

Click the Debug Gnostic Contracts Tab then → the GnosticToken0 tab.

Mint Gnostic Collateral Token 0

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

Mint Gnostic Collateral Token 1

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

Set Allowance for Conditional Token Contract to use Collateral

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

Notes

record addresses, values and hashes. these values will change after each deployment and are for illustration purposes only.

Addresses

  • Hardhat Wallet Address : 0x0a3b031cC1234315a92E647889F9182BC061E8A0

  • Conditional Token Address : 0x5FbDB2315678afecb367f032d93F642f64180aa3

  • Gnostic Token 0 (GT0) : 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512

  • Gnostic Token 1 (GT1) : 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0

IDs

  • Parent Collection : 0x0000000000000000000000000000000000000000000000000000000000000000

  • Question ID 1 : 0x0000000000000000000000000000000000000000000000000000000000000001

  • Question ID 2 : 0x0000000000000000000000000000000000000000000000000000000000000002

Conditional Token Preparation

  • 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

  • use same values and execute prepareCondition

getConditionId Question 2: 0x15d6a8d1501917bb78d09b863412bf66b9c9e2f5f1f624af75531406f454e7bb

Oracle : 0x0a3b031cC1234315a92E647889F9182BC061E8A0

Question ID 2 : 0x0000000000000000000000000000000000000000000000000000000000000002

# Outcomes: 2

  • use same values and execute prepareCondition

Collection IDs

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

Position IDs

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

Creating Positions with Conditional Tokens

Split Positions with Collateral

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

Subscribe to tekh
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.
More from tekh

Skeleton

Skeleton

Skeleton