# Create Gnostic Conditional Token Positions using Scaffold Eth

By [tekh](https://paragraph.com/@quantumtekh) · 2023-08-28

---

### 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
    

[https://docs.gnosis.io/conditionaltokens/docs/ctftutorial01/](https://docs.gnosis.io/conditionaltokens/docs/ctftutorial01/)

*   Scaffold-Eth 2
    

[https://scaffoldeth.io/](https://scaffoldeth.io/)

### 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

[https://gist.github.com/cag/65dc3ddfa03f067dd41ca7121ee3120f](https://gist.github.com/cag/65dc3ddfa03f067dd41ca7121ee3120f)

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

[https://github.com/OwlWilderness/se-2/tree/gnostic-condition](https://github.com/OwlWilderness/se-2/tree/gnostic-condition)

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

[https://github.com/OwlWilderness/se-2/blob/gnostic-condition/packages/hardhat/contracts/ConditionalTokens.sol](https://github.com/OwlWilderness/se-2/blob/gnostic-condition/packages/hardhat/contracts/ConditionalTokens.sol)

    //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

[https://github.com/OwlWilderness/se-2/blob/gnostic-condition/packages/hardhat/contracts/GnosticTokens.sol](https://github.com/OwlWilderness/se-2/blob/gnostic-condition/packages/hardhat/contracts/GnosticTokens.sol)

    //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](https://github.com/OwlWilderness/se-2/tree/gnostic-condition) - reference the below article for instruction.

[https://mirror.xyz/quantumtekh.eth/jnuL3guybvgeXBFShILuiA53Pq9igs4jFcqYZpSqMNo](https://mirror.xyz/quantumtekh.eth/jnuL3guybvgeXBFShILuiA53Pq9igs4jFcqYZpSqMNo)

### Deploy Contracts On Hardhat

Follow instructions in [Scaffold-eth 2 ReadMe](https://github.com/scaffold-eth/scaffold-eth-2) 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](http://localhost:3000/debug)

Click the Faucet Icon in the upper right to fund the hardhat wallet.

![](https://storage.googleapis.com/papyrus_images/b81119e6bbefa9c6870d0950ebbbf52f8703597f53516e0d4adfec1f2cb01409.png)

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

![](https://storage.googleapis.com/papyrus_images/3703796f83ff28a1815371b83cc2387750bdb04774ba9f421e785d7a4d4994ed.png)

### Navigate to Gnostic Token 0

Click the **_Debug Gnostic Contracts_** Tab then → the **_GnosticToken0_** tab.

![](https://storage.googleapis.com/papyrus_images/d434b0168b726c8e4472512976628d0d9c975981ca6b01e94a9742bcc00fda3e.png)

### Mint Gnostic Collateral Token 0

Scroll to the Mint Token section

![](https://storage.googleapis.com/papyrus_images/5f2eacf454847f03bad224b847b19a86524eb7c7d0f9e78389cfa8afbe1cabd5.png)

**_Paste the copied wallet address_** into the **address account** field and enter **_1000_** into the **uint256 amount** field.

**_Click Send_**

![](https://storage.googleapis.com/papyrus_images/de685c99f8b96a9197be1d34a43d7504f2da41f360c403999f8a4614028f4483.png)

Note Supply of GT0 increased to 1000

![](https://storage.googleapis.com/papyrus_images/10ac64e1133baf9660c08487b7935b25272a94d99cab03afcb3873ea7da2de65.png)

Note the GnosticToken0 address by clicking the copy icon

![](https://storage.googleapis.com/papyrus_images/d8e64cdd8ea489a88cf02e7aad803391d9e2154786f88fd92b77950cf3d480c0.png)

### Mint Gnostic Collateral Token 1

Navigate to Gnostic Token 1

![](https://storage.googleapis.com/papyrus_images/47298772d25b5425d337df85508f50d3ec1117f51e32758de531a527813e1320.png)

**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

![](https://storage.googleapis.com/papyrus_images/b8d6fa9e5b37ce9a2b72e64576bf6ab1a96d89c3cecdf96152a0b5aa6c39452f.png)

Navigate to GnosticToken0 Approve Section

![](https://storage.googleapis.com/papyrus_images/bc6fd5bc1bd6da7073a26fb726ba6cc1b08f0d01e9c21ef090496cc5b19d1107.png)

*   Paste copied address into the address spender field.
    
*   Enter 1000 into the amount field
    
*   Click Send
    

![](https://storage.googleapis.com/papyrus_images/0ecf81f6912ba87a5d22a8681d565456ac60c27894d135427e254b86ec3c3358.png)

Repeat Process for Gnostic Token 1

![](https://storage.googleapis.com/papyrus_images/a2d29496c295b94350c4925441f62322bf86fe7d52a64c547f9d5215fe93630e.png)

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

![](https://storage.googleapis.com/papyrus_images/002dab83de88c61b1289eb4f7df1cd6daa75a217b01e558babf089f8a56c6b08.png)

**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
    

![](https://storage.googleapis.com/papyrus_images/75a762e908a28fb25226f331054686d4ddbf86ed1a6b2985b62e35dc03475b2e.png)

**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:**

![](https://storage.googleapis.com/papyrus_images/2abd3fad5795c67ae1a4536fa123b06afafcefa4b08b3ac97fe61afa58f5d570.png)

*   Enter Wallet Address in address account field
    
*   Enter Position ID in uint256 id field
    

![](https://storage.googleapis.com/papyrus_images/e7847ea0b2956b02863066fa24d73dcb4d83d89458e981e8019c2499bbbf4124.png)

---

*Originally published on [tekh](https://paragraph.com/@quantumtekh/create-gnostic-conditional-token-positions-using-scaffold-eth)*
