diff --git a/contracts/.openzeppelin/goerli.json b/contracts/.openzeppelin/goerli.json index abb0c675..4058c77b 100644 --- a/contracts/.openzeppelin/goerli.json +++ b/contracts/.openzeppelin/goerli.json @@ -5485,7 +5485,7 @@ "label": "offers", "offset": 0, "slot": "252", - "type": "t_mapping(t_uint256,t_struct(Offer)7990_storage)", + "type": "t_mapping(t_uint256,t_struct(Offer)2510_storage)", "contract": "HypercertTrader", "src": "src/HypercertTrader.sol:37" }, @@ -5511,7 +5511,7 @@ "label": "address", "numberOfBytes": "20" }, - "t_array(t_struct(AcceptedToken)8002_storage)dyn_storage": { + "t_array(t_struct(AcceptedToken)2522_storage)dyn_storage": { "label": "struct IHypercertTrader.AcceptedToken[]", "numberOfBytes": "32" }, @@ -5531,7 +5531,7 @@ "label": "bool", "numberOfBytes": "1" }, - "t_enum(OfferStatus)7997": { + "t_enum(OfferStatus)2517": { "label": "enum IHypercertTrader.OfferStatus", "members": [ "Open", @@ -5540,7 +5540,7 @@ ], "numberOfBytes": "1" }, - "t_enum(OfferType)7993": { + "t_enum(OfferType)2513": { "label": "enum IHypercertTrader.OfferType", "members": [ "Units", @@ -5552,7 +5552,7 @@ "label": "mapping(address => mapping(uint256 => uint256))", "numberOfBytes": "32" }, - "t_mapping(t_uint256,t_struct(Offer)7990_storage)": { + "t_mapping(t_uint256,t_struct(Offer)2510_storage)": { "label": "mapping(uint256 => struct IHypercertTrader.Offer)", "numberOfBytes": "32" }, @@ -5560,7 +5560,7 @@ "label": "mapping(uint256 => uint256)", "numberOfBytes": "32" }, - "t_struct(AcceptedToken)8002_storage": { + "t_struct(AcceptedToken)2522_storage": { "label": "struct IHypercertTrader.AcceptedToken", "members": [ { @@ -5578,7 +5578,7 @@ ], "numberOfBytes": "64" }, - "t_struct(Offer)7990_storage": { + "t_struct(Offer)2510_storage": { "label": "struct IHypercertTrader.Offer", "members": [ { @@ -5619,19 +5619,274 @@ }, { "label": "offerType", - "type": "t_enum(OfferType)7993", + "type": "t_enum(OfferType)2513", "offset": 0, "slot": "6" }, { "label": "status", - "type": "t_enum(OfferStatus)7997", + "type": "t_enum(OfferStatus)2517", "offset": 1, "slot": "6" }, { "label": "acceptedTokens", - "type": "t_array(t_struct(AcceptedToken)8002_storage)dyn_storage", + "type": "t_array(t_struct(AcceptedToken)2522_storage)dyn_storage", + "offset": 0, + "slot": "7" + } + ], + "numberOfBytes": "256" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } + }, + "c448a5dca6b776aedb55eb5857ea7c6a03d1ccd3ff709786879396d71bf7dbb2": { + "address": "0x038c990018b9Aab4aA2496E592E668EAD77aF72B", + "txHash": "0xe07f42a41b70affd1fdd08ce8011f55a35b0e62a9ef67d0b5c4daa04b6028f60", + "layout": { + "solcVersion": "0.8.16", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_paused", + "offset": 0, + "slot": "101", + "type": "t_bool", + "contract": "PausableUpgradeable", + "src": "lib/openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol:29" + }, + { + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage", + "contract": "PausableUpgradeable", + "src": "lib/openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol:116" + }, + { + "label": "__gap", + "offset": 0, + "slot": "151", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "lib/openzeppelin-contracts-upgradeable/contracts/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:211" + }, + { + "label": "__gap", + "offset": 0, + "slot": "201", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol:107" + }, + { + "label": "totalUnitsForSale", + "offset": 0, + "slot": "251", + "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))", + "contract": "HypercertTrader", + "src": "src/HypercertTrader.sol:36" + }, + { + "label": "offers", + "offset": 0, + "slot": "252", + "type": "t_mapping(t_uint256,t_struct(Offer)8003_storage)", + "contract": "HypercertTrader", + "src": "src/HypercertTrader.sol:37" + }, + { + "label": "_offerCounter", + "offset": 0, + "slot": "253", + "type": "t_uint256", + "contract": "HypercertTrader", + "src": "src/HypercertTrader.sol:38" + }, + { + "label": "__gap", + "offset": 0, + "slot": "254", + "type": "t_array(t_uint256)27_storage", + "contract": "HypercertTrader", + "src": "src/HypercertTrader.sol:392" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_struct(AcceptedToken)8015_storage)dyn_storage": { + "label": "struct IHypercertTrader.AcceptedToken[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)27_storage": { + "label": "uint256[27]", + "numberOfBytes": "864" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_enum(OfferStatus)8010": { + "label": "enum IHypercertTrader.OfferStatus", + "members": [ + "Open", + "Fulfilled", + "Cancelled" + ], + "numberOfBytes": "1" + }, + "t_enum(OfferType)8006": { + "label": "enum IHypercertTrader.OfferType", + "members": [ + "Units", + "Fraction" + ], + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_mapping(t_uint256,t_uint256))": { + "label": "mapping(address => mapping(uint256 => uint256))", + "numberOfBytes": "32" + }, + "t_mapping(t_uint256,t_struct(Offer)8003_storage)": { + "label": "mapping(uint256 => struct IHypercertTrader.Offer)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint256,t_uint256)": { + "label": "mapping(uint256 => uint256)", + "numberOfBytes": "32" + }, + "t_struct(AcceptedToken)8015_storage": { + "label": "struct IHypercertTrader.AcceptedToken", + "members": [ + { + "label": "token", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "minimumAmountPerUnit", + "type": "t_uint256", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Offer)8003_storage": { + "label": "struct IHypercertTrader.Offer", + "members": [ + { + "label": "offerer", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "hypercertContract", + "type": "t_address", + "offset": 0, + "slot": "1" + }, + { + "label": "fractionID", + "type": "t_uint256", + "offset": 0, + "slot": "2" + }, + { + "label": "unitsAvailable", + "type": "t_uint256", + "offset": 0, + "slot": "3" + }, + { + "label": "minUnitsPerTrade", + "type": "t_uint256", + "offset": 0, + "slot": "4" + }, + { + "label": "maxUnitsPerTrade", + "type": "t_uint256", + "offset": 0, + "slot": "5" + }, + { + "label": "offerType", + "type": "t_enum(OfferType)8006", + "offset": 0, + "slot": "6" + }, + { + "label": "status", + "type": "t_enum(OfferStatus)8010", + "offset": 1, + "slot": "6" + }, + { + "label": "acceptedTokens", + "type": "t_array(t_struct(AcceptedToken)8015_storage)dyn_storage", "offset": 0, "slot": "7" } diff --git a/contracts/src/HypercertTrader.sol b/contracts/src/HypercertTrader.sol index dfc08c1a..7f9aae3f 100644 --- a/contracts/src/HypercertTrader.sol +++ b/contracts/src/HypercertTrader.sol @@ -46,6 +46,10 @@ contract HypercertTrader is IHypercertTrader, Initializable, OwnableUpgradeable, __UUPSUpgradeable_init(); } + function getOffer(uint256 offerID) external view returns (Offer memory) { + return offers[offerID]; + } + /** * @dev Creates a new offer to sell Hypercert tokens. * @param hypercertContract The address of the Hypercert token contract. diff --git a/contracts/test/foundry/HypercertTrader.admin.t.sol b/contracts/test/foundry/HypercertTrader.admin.t.sol index 4cf645c6..3b7ee0eb 100644 --- a/contracts/test/foundry/HypercertTrader.admin.t.sol +++ b/contracts/test/foundry/HypercertTrader.admin.t.sol @@ -24,10 +24,6 @@ contract HypercertTraderHelper is HypercertTrader { HypercertMinter public hypercertMinter = new HypercertMinter(); - function getOffer(uint256 key) external view returns (Offer memory) { - return offers[key]; - } - function getOfferCount() external view returns (uint256) { return _offerCounter; } diff --git a/contracts/test/foundry/HypercertTrader.offers.t.sol b/contracts/test/foundry/HypercertTrader.offers.t.sol index 71c09133..6901b314 100644 --- a/contracts/test/foundry/HypercertTrader.offers.t.sol +++ b/contracts/test/foundry/HypercertTrader.offers.t.sol @@ -23,10 +23,6 @@ contract HypercertTraderHelper is HypercertTrader { HypercertMinter public hypercertMinter = new HypercertMinter(); - function getOffer(uint256 key) external view returns (Offer memory) { - return offers[key]; - } - function getOfferCount() external view returns (uint256) { return _offerCounter; } @@ -39,7 +35,7 @@ contract HypercertTraderHelper is HypercertTrader { uint256 minUnitsPerTrade, uint256 maxUnitsPerTrade, AcceptedToken[] memory acceptedTokens - ) external { + ) external payable { _validateOffer( offerer, hypercertContract, diff --git a/contracts/test/foundry/HypercertTrader.sales.t.sol b/contracts/test/foundry/HypercertTrader.sales.t.sol index c086fdd4..07c0216a 100644 --- a/contracts/test/foundry/HypercertTrader.sales.t.sol +++ b/contracts/test/foundry/HypercertTrader.sales.t.sol @@ -24,10 +24,6 @@ contract HypercertTraderHelper is HypercertTrader, PRBTest, StdCheats, StdUtils HypercertMinter public hypercertMinter = new HypercertMinter(); - function getOffer(uint256 key) external view returns (Offer memory) { - return offers[key]; - } - function getOfferCount() external view returns (uint256) { return _offerCounter; } diff --git a/docs/docs/developer/api/contracts/HypercertTrader.md b/docs/docs/developer/api/contracts/HypercertTrader.md index 4a5c9b4e..e31e8840 100644 --- a/docs/docs/developer/api/contracts/HypercertTrader.md +++ b/docs/docs/developer/api/contracts/HypercertTrader.md @@ -87,6 +87,24 @@ function createOffer(address hypercertContract, uint256 fractionID, uint256 unit | ------- | ------- | ----------- | | offerID | uint256 | undefined | +### getOffer + +```solidity +function getOffer(uint256 offerID) external view returns (struct IHypercertTrader.Offer) +``` + +#### Parameters + +| Name | Type | Description | +| ------- | ------- | ----------- | +| offerID | uint256 | undefined | + +#### Returns + +| Name | Type | Description | +| ---- | ---------------------- | ----------- | +| \_0 | IHypercertTrader.Offer | undefined | + ### initialize ```solidity diff --git a/graph/abis/HypercertTrader.json b/graph/abis/HypercertTrader.json index 4851032d..1f114e5e 100644 --- a/graph/abis/HypercertTrader.json +++ b/graph/abis/HypercertTrader.json @@ -1,16 +1,36 @@ [ - { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, { - "inputs": [{ "internalType": "string", "name": "", "type": "string" }], + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], "name": "InvalidBuy", "type": "error" }, { - "inputs": [{ "internalType": "string", "name": "", "type": "string" }], + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], "name": "InvalidOffer", "type": "error" }, - { "inputs": [], "name": "NotAllowed", "type": "error" }, + { + "inputs": [], + "name": "NotAllowed", + "type": "error" + }, { "anonymous": false, "inputs": [ @@ -233,14 +253,26 @@ }, { "inputs": [ - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "uint256[]", "name": "offerIDs", "type": "uint256[]" }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "offerIDs", + "type": "uint256[]" + }, { "internalType": "uint256[]", "name": "unitAmounts", "type": "uint256[]" }, - { "internalType": "address[]", "name": "buyTokens", "type": "address[]" }, + { + "internalType": "address[]", + "name": "buyTokens", + "type": "address[]" + }, { "internalType": "uint256[]", "name": "tokenAmountsPerUnit", @@ -254,10 +286,26 @@ }, { "inputs": [ - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "uint256", "name": "offerID", "type": "uint256" }, - { "internalType": "uint256", "name": "unitAmount", "type": "uint256" }, - { "internalType": "address", "name": "buyToken", "type": "address" }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offerID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "unitAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "buyToken", + "type": "address" + }, { "internalType": "uint256", "name": "tokenAmountPerUnit", @@ -271,7 +319,11 @@ }, { "inputs": [ - { "internalType": "uint256", "name": "offerID", "type": "uint256" } + { + "internalType": "uint256", + "name": "offerID", + "type": "uint256" + } ], "name": "cancelOffer", "outputs": [], @@ -285,8 +337,16 @@ "name": "hypercertContract", "type": "address" }, - { "internalType": "uint256", "name": "fractionID", "type": "uint256" }, - { "internalType": "uint256", "name": "unitsForSale", "type": "uint256" }, + { + "internalType": "uint256", + "name": "fractionID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "unitsForSale", + "type": "uint256" + }, { "internalType": "uint256", "name": "minUnitsPerTrade", @@ -299,7 +359,11 @@ }, { "components": [ - { "internalType": "address", "name": "token", "type": "address" }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, { "internalType": "uint256", "name": "minimumAmountPerUnit", @@ -313,11 +377,93 @@ ], "name": "createOffer", "outputs": [ - { "internalType": "uint256", "name": "offerID", "type": "uint256" } + { + "internalType": "uint256", + "name": "offerID", + "type": "uint256" + } ], "stateMutability": "payable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offerID", + "type": "uint256" + } + ], + "name": "getOffer", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "offerer", + "type": "address" + }, + { + "internalType": "address", + "name": "hypercertContract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fractionID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "unitsAvailable", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minUnitsPerTrade", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxUnitsPerTrade", + "type": "uint256" + }, + { + "internalType": "enum IHypercertTrader.OfferType", + "name": "offerType", + "type": "uint8" + }, + { + "internalType": "enum IHypercertTrader.OfferStatus", + "name": "status", + "type": "uint8" + }, + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minimumAmountPerUnit", + "type": "uint256" + } + ], + "internalType": "struct IHypercertTrader.AcceptedToken[]", + "name": "acceptedTokens", + "type": "tuple[]" + } + ], + "internalType": "struct IHypercertTrader.Offer", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "initialize", @@ -326,16 +472,30 @@ "type": "function" }, { - "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], "name": "offers", "outputs": [ - { "internalType": "address", "name": "offerer", "type": "address" }, + { + "internalType": "address", + "name": "offerer", + "type": "address" + }, { "internalType": "address", "name": "hypercertContract", "type": "address" }, - { "internalType": "uint256", "name": "fractionID", "type": "uint256" }, + { + "internalType": "uint256", + "name": "fractionID", + "type": "uint256" + }, { "internalType": "uint256", "name": "unitsAvailable", @@ -368,7 +528,13 @@ { "inputs": [], "name": "owner", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], "stateMutability": "view", "type": "function" }, @@ -382,14 +548,26 @@ { "inputs": [], "name": "paused", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "proxiableUUID", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], "stateMutability": "view", "type": "function" }, @@ -402,17 +580,35 @@ }, { "inputs": [ - { "internalType": "address", "name": "", "type": "address" }, - { "internalType": "uint256", "name": "", "type": "uint256" } + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } ], "name": "totalUnitsForSale", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], "stateMutability": "view", "type": "function" }, { "inputs": [ - { "internalType": "address", "name": "newOwner", "type": "address" } + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } ], "name": "transferOwnership", "outputs": [], @@ -446,7 +642,11 @@ "name": "newImplementation", "type": "address" }, - { "internalType": "bytes", "name": "data", "type": "bytes" } + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } ], "name": "upgradeToAndCall", "outputs": [], diff --git a/graph/generated/HypercertTrader/HypercertTrader.ts b/graph/generated/HypercertTrader/HypercertTrader.ts index 58e780d5..36aef88f 100644 --- a/graph/generated/HypercertTrader/HypercertTrader.ts +++ b/graph/generated/HypercertTrader/HypercertTrader.ts @@ -250,6 +250,54 @@ export class Upgraded__Params { } } +export class HypercertTrader__getOfferResultValue0Struct extends ethereum.Tuple { + get offerer(): Address { + return this[0].toAddress(); + } + + get hypercertContract(): Address { + return this[1].toAddress(); + } + + get fractionID(): BigInt { + return this[2].toBigInt(); + } + + get unitsAvailable(): BigInt { + return this[3].toBigInt(); + } + + get minUnitsPerTrade(): BigInt { + return this[4].toBigInt(); + } + + get maxUnitsPerTrade(): BigInt { + return this[5].toBigInt(); + } + + get offerType(): i32 { + return this[6].toI32(); + } + + get status(): i32 { + return this[7].toI32(); + } + + get acceptedTokens(): Array { + return this[8].toTupleArray(); + } +} + +export class HypercertTrader__getOfferResultValue0AcceptedTokensStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get minimumAmountPerUnit(): BigInt { + return this[1].toBigInt(); + } +} + export class HypercertTrader__offersResult { value0: Address; value1: Address; @@ -337,6 +385,37 @@ export class HypercertTrader extends ethereum.SmartContract { return new HypercertTrader("HypercertTrader", address); } + getOffer(offerID: BigInt): HypercertTrader__getOfferResultValue0Struct { + let result = super.call( + "getOffer", + "getOffer(uint256):((address,address,uint256,uint256,uint256,uint256,uint8,uint8,(address,uint256)[]))", + [ethereum.Value.fromUnsignedBigInt(offerID)], + ); + + return changetype( + result[0].toTuple(), + ); + } + + try_getOffer( + offerID: BigInt, + ): ethereum.CallResult { + let result = super.tryCall( + "getOffer", + "getOffer(uint256):((address,address,uint256,uint256,uint256,uint256,uint8,uint8,(address,uint256)[]))", + [ethereum.Value.fromUnsignedBigInt(offerID)], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue( + changetype( + value[0].toTuple(), + ), + ); + } + offers(param0: BigInt): HypercertTrader__offersResult { let result = super.call( "offers", diff --git a/graph/generated/schema.ts b/graph/generated/schema.ts index de8e18a1..cf492abf 100644 --- a/graph/generated/schema.ts +++ b/graph/generated/schema.ts @@ -331,6 +331,10 @@ export class ClaimToken extends Entity { set units(value: BigInt) { this.set("units", Value.fromBigInt(value)); } + + get offers(): OfferLoader { + return new OfferLoader("ClaimToken", this.get("id")!.toString(), "offers"); + } } export class Token extends Entity { @@ -384,6 +388,40 @@ export class Token extends Entity { set name(value: string) { this.set("name", Value.fromString(value)); } + + get symbol(): string | null { + let value = this.get("symbol"); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toString(); + } + } + + set symbol(value: string | null) { + if (!value) { + this.unset("symbol"); + } else { + this.set("symbol", Value.fromString(value)); + } + } + + get decimals(): BigInt | null { + let value = this.get("decimals"); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set decimals(value: BigInt | null) { + if (!value) { + this.unset("decimals"); + } else { + this.set("decimals", Value.fromBigInt(value)); + } + } } export class AcceptedToken extends Entity { @@ -689,3 +727,21 @@ export class Trade extends Entity { this.set("amountPerUnit", Value.fromBigInt(value)); } } + +export class OfferLoader extends Entity { + _entity: string; + _field: string; + _id: string; + + constructor(entity: string, id: string, field: string) { + super(); + this._entity = entity; + this._id = id; + this._field = field; + } + + load(): Offer[] { + let value = store.loadRelated(this._entity, this._id, this._field); + return changetype(value); + } +} diff --git a/graph/package.json b/graph/package.json index e8f03fa3..8ff42396 100644 --- a/graph/package.json +++ b/graph/package.json @@ -24,7 +24,7 @@ "test": "graph test" }, "dependencies": { - "@graphprotocol/graph-cli": "0.56.0" + "@graphprotocol/graph-cli": "0.57.0" }, "devDependencies": { "@graphprotocol/graph-ts": "0.31.0", diff --git a/graph/schema.graphql b/graph/schema.graphql index e42546a0..d6ec32ef 100644 --- a/graph/schema.graphql +++ b/graph/schema.graphql @@ -22,11 +22,14 @@ type ClaimToken @entity { claim: Claim! owner: Bytes! units: BigInt! + offers: [Offer!] @derivedFrom(field: "fractionID") } type Token @entity { id: String! name: String! + symbol: String + decimals: BigInt } type AcceptedToken @entity { diff --git a/graph/src/utils.ts b/graph/src/utils.ts index 4511dcaa..e15b9054 100644 --- a/graph/src/utils.ts +++ b/graph/src/utils.ts @@ -110,6 +110,7 @@ export function getOrCreateToken(token: Address): Token { export function getOrCreateAcceptedToken( offerID: BigInt, token: Address, + minimumAmountPerUnit: BigInt, ): AcceptedToken { const _acceptedTokenID = offerID .toHexString() @@ -119,11 +120,12 @@ export function getOrCreateAcceptedToken( if (acceptedToken == null) { acceptedToken = new AcceptedToken(_acceptedTokenID); acceptedToken.token = getOrCreateToken(token).id; - acceptedToken.minimumAmountPerUnit = BigInt.fromI32(0); + acceptedToken.minimumAmountPerUnit = minimumAmountPerUnit; acceptedToken.accepted = true; acceptedToken.save(); } + log.debug("Returning acceptedToken: {}", [_acceptedTokenID]); return acceptedToken; } @@ -142,16 +144,27 @@ export function getOrCreateOffer( let offer = Offer.load(_offerID); if (offer == null) { - const offerOnChain = _traderContract.offers(offerID); + const offerOnChain = _traderContract.getOffer(offerID); offer = new Offer(_offerID); offer.fractionID = _fractionID; - offer.unitsAvailable = offerOnChain.getUnitsAvailable(); - offer.minUnitsPerTrade = offerOnChain.getMinUnitsPerTrade(); - offer.maxUnitsPerTrade = offerOnChain.getMaxUnitsPerTrade(); + offer.unitsAvailable = offerOnChain.unitsAvailable; + offer.minUnitsPerTrade = offerOnChain.minUnitsPerTrade; + offer.maxUnitsPerTrade = offerOnChain.maxUnitsPerTrade; + offer.acceptedTokens = []; offer.status = "Open"; - offer.acceptedTokens = [getOrCreateAcceptedToken(offerID, ZERO_ADDRESS).id]; - offer.save(); + + for (let i = 0; i < offerOnChain.acceptedTokens.length; i++) { + const _acceptedToken = offerOnChain.acceptedTokens[i]; + const parsedToken = getOrCreateAcceptedToken( + offerID, + _acceptedToken.token, + _acceptedToken.minimumAmountPerUnit, + ); + offer.acceptedTokens.push(parsedToken.id.toString()); + } + log.debug("Created offerID: {}", [_offerID]); + offer.save(); } return offer; diff --git a/graph/tests/hypercert-trader.test.ts b/graph/tests/hypercert-trader.test.ts index 691053dc..51230b74 100644 --- a/graph/tests/hypercert-trader.test.ts +++ b/graph/tests/hypercert-trader.test.ts @@ -1,9 +1,10 @@ import { handleOfferCreated } from "../src/hypercert-trader"; +import { ZERO_ADDRESS } from "../src/utils"; import { DEFAULT_TRADER_ADDRESS, createOfferCreatedEvent, } from "./hypercert-trader-utils"; -import { Address, BigInt, ethereum } from "@graphprotocol/graph-ts"; +import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; import { assert, describe, @@ -19,26 +20,42 @@ import { describe("Describe entity assertions", () => { beforeAll(() => { + let acceptedToken: Array = [ + ethereum.Value.fromAddress( + Address.fromString("0x89205A3A3b2A69De6Dbf7f01ED13B2108B2c43e7"), + ), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)), + ]; + + let tuple = changetype(acceptedToken); + let tupleValue = ethereum.Value.fromTupleArray([tuple]); + + const returnValues = [ + ethereum.Value.fromAddress( + Address.fromString("0x0000000000000000000000000000000000000003"), + ), + ethereum.Value.fromAddress( + Address.fromString("0x0000000000000000000000000000000000000004"), + ), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)), + ethereum.Value.fromTupleArray([tuple]), + ]; + + let returnValueTuple = changetype(returnValues); + let returnValue = ethereum.Value.fromTuple(returnValueTuple); + createMockedFunction( DEFAULT_TRADER_ADDRESS, - "offers", - "offers(uint256):(address,address,uint256,uint256,uint256,uint256,uint8,uint8)", + "getOffer", + "getOffer(uint256):((address,address,uint256,uint256,uint256,uint256,uint8,uint8,(address,uint256)[]))", ) .withArgs([ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1))]) - .returns([ - ethereum.Value.fromAddress( - Address.fromString("0x0000000000000000000000000000000000000003"), - ), - ethereum.Value.fromAddress( - Address.fromString("0x0000000000000000000000000000000000000004"), - ), - ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)), - ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)), - ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)), - ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)), - ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)), - ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)), - ]); + .returns([returnValue]); }); afterAll(() => {