From 0a47ce44795182c650bec7284f96002397e04924 Mon Sep 17 00:00:00 2001 From: geovgy Date: Fri, 18 Aug 2023 13:44:38 -0400 Subject: [PATCH 1/8] Update subgraph to include split-escrow type and mappings --- .../abis/01/SmartInvoiceSplitEscrow01.json | 719 ++++++++++++++++++ packages/subgraph/src/mappings/01/factory.ts | 3 + .../src/mappings/01/helpers/split-escrow.ts | 202 +++++ packages/subgraph/src/mappings/01/utils.ts | 7 + packages/subgraph/src/schema.graphql | 3 + packages/subgraph/subgraph.template.yaml | 41 + packages/subgraph/subgraph.yaml | 43 ++ 7 files changed, 1018 insertions(+) create mode 100644 packages/subgraph/src/abis/01/SmartInvoiceSplitEscrow01.json create mode 100644 packages/subgraph/src/mappings/01/helpers/split-escrow.ts diff --git a/packages/subgraph/src/abis/01/SmartInvoiceSplitEscrow01.json b/packages/subgraph/src/abis/01/SmartInvoiceSplitEscrow01.json new file mode 100644 index 00000000..fb3e20a7 --- /dev/null +++ b/packages/subgraph/src/abis/01/SmartInvoiceSplitEscrow01.json @@ -0,0 +1,719 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "SmartInvoiceSplitEscrow", + "sourceName": "contracts/SmartInvoiceSplitEscrow.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "details", + "type": "bytes32" + } + ], + "name": "DetailsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "details", + "type": "bytes32" + } + ], + "name": "Lock", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "invoice", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "milestones", + "type": "uint256[]" + } + ], + "name": "MilestonesAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "milestone", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Release", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "resolver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "clientAward", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "providerAward", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "resolutionFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "details", + "type": "bytes32" + } + ], + "name": "Resolve", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "resolver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "clientAward", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "providerAward", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ruling", + "type": "uint256" + } + ], + "name": "Rule", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_arbitrator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "Ruling", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "client", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "invoice", + "type": "address" + } + ], + "name": "Verified", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_TERMINATION_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NUM_RULING_OPTIONS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "RULINGS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_milestones", + "type": "uint256[]" + }, + { + "internalType": "bytes32", + "name": "_details", + "type": "bytes32" + } + ], + "name": "addMilestones", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_milestones", + "type": "uint256[]" + } + ], + "name": "addMilestones", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "amounts", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "client", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "dao", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "daoFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "details", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disputeId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAmounts", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "_amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initLock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_details", + "type": "bytes32" + } + ], + "name": "lock", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "locked", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "milestone", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "provider", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_milestone", + "type": "uint256" + } + ], + "name": "release", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "release", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "releaseTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "released", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "resolutionRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_clientAward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_providerAward", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_details", + "type": "bytes32" + } + ], + "name": "resolve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resolver", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "resolverType", + "outputs": [ + { + "internalType": "enum SmartInvoiceEscrow.ADR", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "rule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "terminationTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "total", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "verify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "withdrawTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "wrappedNativeToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x6001610140818152610160829052608090815261018082815260006101a081905260a09190915260036101c08181526101e085905260c05261020084815261022085905260e05261024084815261026091909152610100526102c06040526102809081526102a0929092526101209190915262000081906002906006620000a9565b506000601155600060135560006014553480156200009e57600080fd5b5060018055620001bc565b8260068101928215620000e8579160200282015b82811115620000e8578251620000d79083906002620000fa565b5091602001919060010190620000bd565b50620000f692915062000190565b5090565b600183019183908215620001825791602002820160005b838211156200015157835183826101000a81548160ff021916908360ff160217905550926020019260010160208160000104928301926001030262000111565b8015620001805782816101000a81549060ff021916905560010160208160000104928301926001030262000151565b505b50620000f6929150620001a6565b80821115620000f6576000815560010162000190565b80821115620000f6576000815560010162000190565b61309480620001cc6000396000f3fe6080604052600436106101fd5760003560e01c80635ce6288c1161010d578063a7d07c82116100a0578063e38f48611161006f578063e38f4861146106a6578063e86dad24146106bb578063f51cf927146106d3578063fc0c546a14610705578063fc735e991461072557610338565b8063a7d07c8214610630578063ce4254ce14610650578063cf30901214610666578063dbac78061461069057610338565b806386d1a69f116100dc57806386d1a69f146105cf57806387b0be48146105e4578063946f2e4814610604578063961325211461061a57610338565b80635ce6288c1461054c57806370ff6bd714610561578063786ad4eb1461058f578063868af224146105af57610338565b80632e77c8d2116101905780633d370b4e1161015f5780633d370b4e146104b45780634162169f146104d657806345f0a44f146104f657806349df728c14610516578063565974d31461053657610338565b80632e77c8d214610449578063311a6c561461045f57806337bdc99b1461047f5780633ccfd60b1461049f57610338565b8063109e94cf116101cc578063109e94cf146103cf57806317fcb39b146103ef5780632957b8391461040f5780632ddbd13a1461043357610338565b806301670ba91461033d57806304f3bcec146103525780630721711d1461038f578063085d4883146103af57610338565b366103385760125460ff161561022e5760405162461bcd60e51b815260040161022590612e91565b60405180910390fd5b600854600c546001600160a01b039081169116146102845760405162461bcd60e51b815260206004820152601360248201527210bbb930b83832b22730ba34bb32aa37b5b2b760691b6044820152606401610225565b600860009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156102d457600080fd5b505af11580156102e8573d6000803e3d6000fd5b50505050506102f43390565b6001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405161032e91815260200190565b60405180910390a2005b600080fd5b61035061034b366004612ca5565b61073a565b005b34801561035e57600080fd5b50600b54610372906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561039b57600080fd5b506103506103aa366004612b58565b610a0f565b3480156103bb57600080fd5b50600a54610372906001600160a01b031681565b3480156103db57600080fd5b50600954610372906001600160a01b031681565b3480156103fb57600080fd5b50600854610372906001600160a01b031681565b34801561041b57600080fd5b5061042560175481565b604051908152602001610386565b34801561043f57600080fd5b5061042560115481565b34801561045557600080fd5b5061042560155481565b34801561046b57600080fd5b5061035061047a366004612cd5565b610b59565b34801561048b57600080fd5b5061035061049a366004612ca5565b610ee8565b3480156104ab57600080fd5b50610350611232565b3480156104c057600080fd5b506104c9611268565b6040516103869190612da3565b3480156104e257600080fd5b50601654610372906001600160a01b031681565b34801561050257600080fd5b50610425610511366004612ca5565b6112c0565b34801561052257600080fd5b50610350610531366004612a7b565b6112e1565b34801561054257600080fd5b50610425600f5481565b34801561055857600080fd5b50610425600581565b34801561056d57600080fd5b50600a5461058290600160a01b900460ff1681565b6040516103869190612de7565b34801561059b57600080fd5b506103506105aa366004612c3f565b61142a565b3480156105bb57600080fd5b506103506105ca366004612bff565b61143a565b3480156105db57600080fd5b5061035061144a565b3480156105f057600080fd5b506103506105ff366004612a7b565b61147a565b34801561061057600080fd5b50610425600e5481565b34801561062657600080fd5b5061042560145481565b34801561063c57600080fd5b5061035061064b366004612cf6565b611579565b34801561065c57600080fd5b50610425600d5481565b34801561067257600080fd5b506012546106809060ff1681565b6040519015158152602001610386565b34801561069c57600080fd5b5061042560135481565b3480156106b257600080fd5b50610350611876565b3480156106c757600080fd5b506104256303c30ab081565b3480156106df57600080fd5b506106f36106ee366004612cd5565b6118e4565b60405160ff9091168152602001610386565b34801561071157600080fd5b50600c54610372906001600160a01b031681565b34801561073157600080fd5b50610350611920565b6002600154141561075d5760405162461bcd60e51b815260040161022590612ed7565b600260015560125460ff16156107855760405162461bcd60e51b815260040161022590612e91565b600c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b1580156107c957600080fd5b505afa1580156107dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108019190612cbd565b9050600081116108235760405162461bcd60e51b815260040161022590612eb1565b600d5442106108615760405162461bcd60e51b815260206004820152600a6024820152691d195c9b5a5b985d195960b21b6044820152606401610225565b6009546001600160a01b0316336001600160a01b031614806108965750600a546001600160a01b0316336001600160a01b0316145b6108cb5760405162461bcd60e51b815260206004820152600660248201526521706172747960d01b6044820152606401610225565b6001600a54600160a01b900460ff1660018111156108f957634e487b7160e01b600052602160045260246000fd5b14156109b157600b54600f546040516001600160a01b039092169163c13517e191349160059161092f9160200190815260200190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161095b929190612f0e565b6020604051808303818588803b15801561097457600080fd5b505af1158015610988573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109ad9190612cbd565b6015555b6012805460ff191660011790556109c53390565b6001600160a01b03167fe55f8011a92f4874f2b5795bfe755853e25c72d78f99ce599a78e505178ba240836040516109ff91815260200190565b60405180910390a2505060018055565b6000610a1b6001611984565b90508015610a33576000805461ff0019166101001790555b6001600160a01b038616610a7c5760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b210383937bb34b232b960811b6044820152606401610225565b610a868383611a0a565b600a80546001600160a01b0319166001600160a01b038816179055610aad60108686612962565b506000805b601054811015610b075760108181548110610add57634e487b7160e01b600052603260045260246000fd5b906000526020600020015482610af39190612f27565b915080610aff81612fea565b915050610ab2565b506011558015610b51576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60026001541415610b7c5760405162461bcd60e51b815260040161022590612ed7565b60026001908155600a54600160a01b900460ff166001811115610baf57634e487b7160e01b600052602160045260246000fd5b14610bf35760405162461bcd60e51b815260206004820152601460248201527310b0b93134ba3930ba37b9103932b9b7b63b32b960611b6044820152606401610225565b60125460ff16610c2f5760405162461bcd60e51b8152602060048201526007602482015266085b1bd8dad95960ca1b6044820152606401610225565b600b546001600160a01b0316336001600160a01b031614610c7e5760405162461bcd60e51b815260206004820152600960248201526810b932b9b7b63b32b960b91b6044820152606401610225565b6015548214610cc55760405162461bcd60e51b81526020600482015260136024820152721a5b98dbdc9c9958dd08191a5cdc1d5d195259606a1b6044820152606401610225565b6005811115610d075760405162461bcd60e51b815260206004820152600e60248201526d696e76616c69642072756c696e6760901b6044820152606401610225565b600c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b158015610d4b57600080fd5b505afa158015610d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d839190612cbd565b905060008111610da55760405162461bcd60e51b815260040161022590612eb1565b6000610db083611e34565b80516020820151919250906000610dc78284612f3f565b905060008160ff168360ff1687610dde9190612f84565b610de89190612f64565b90506000610df68288612fa3565b90508115610e1457600c54610e14906001600160a01b031683611ef9565b8015610e3757600954600c54610e37916001600160a01b03918216911683611f64565b6010546013556012805460ff19169055600b5460408051838152602081018590529081018a90526001600160a01b03909116907ff08a08afe8a39853d7db7dd0a42f0cdb68a64ee36a554e68c32219f381e5669e9060600160405180910390a2600b546040518981528a916001600160a01b0316907f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222769060200160405180910390a350506001805550505050505050565b60026001541415610f0b5760405162461bcd60e51b815260040161022590612ed7565b600260015560125460ff1615610f335760405162461bcd60e51b815260040161022590612e91565b6009546001600160a01b0316336001600160a01b031614610f665760405162461bcd60e51b815260040161022590612e70565b601354811015610fab5760405162461bcd60e51b815260206004820152601060248201526f1b5a5b195cdd1bdb99481c185cdcd95960821b6044820152606401610225565b6010548110610ff05760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964206d696c6573746f6e6560781b6044820152606401610225565b600c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561103457600080fd5b505afa158015611048573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106c9190612cbd565b6013549091506000905b8381116111ac5760105461108c90600190612fa3565b811480156110cf575082601082815481106110b757634e487b7160e01b600052603260045260246000fd5b9060005260206000200154836110cd9190612f27565b105b1561110e5760008051602061303f833981519152816110ee8486612fa3565b6040805192835260208301919091520160405180910390a182915061119a565b60008051602061303f833981519152816010838154811061113f57634e487b7160e01b600052603260045260246000fd5b6000918252602091829020015460408051938452918301520160405180910390a16010818154811061118157634e487b7160e01b600052603260045260246000fd5b9060005260206000200154826111979190612f27565b91505b806111a481612fea565b915050611076565b50808210156111f45760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b6044820152606401610225565b600c5461120a906001600160a01b031682611ef9565b806014546112189190612f27565b601455611226836001612f27565b60135550506001805550565b600260015414156112555760405162461bcd60e51b815260040161022590612ed7565b6002600155611262611fb6565b60018055565b606060108054806020026020016040519081016040528092919081815260200182805480156112b657602002820191906000526020600020905b8154815260200190600101908083116112a2575b5050505050905090565b601081815481106112d057600080fd5b600091825260209091200154905081565b600260015414156113045760405162461bcd60e51b815260040161022590612ed7565b6002600155600c546001600160a01b038281169116141561132c57611327611fb6565b611423565b600d54421161136b5760405162461bcd60e51b815260206004820152600b60248201526a085d195c9b5a5b985d195960aa1b6044820152606401610225565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b1580156113ad57600080fd5b505afa1580156113c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e59190612cbd565b9050600081116114075760405162461bcd60e51b815260040161022590612eb1565b600954611421906001600160a01b03848116911683611f64565b505b5060018055565b611435838383612109565b505050565b61144682826000612109565b5050565b6002600154141561146d5760405162461bcd60e51b815260040161022590612ed7565b60026001556112626124b6565b6002600154141561149d5760405162461bcd60e51b815260040161022590612ed7565b6002600155600c546001600160a01b03828116911614156114c0576113276124b6565b6009546001600160a01b0316336001600160a01b0316146114f35760405162461bcd60e51b815260040161022590612e70565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b15801561153557600080fd5b505afa158015611549573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156d9190612cbd565b90506114218282611ef9565b6002600154141561159c5760405162461bcd60e51b815260040161022590612ed7565b60026001556000600a54600160a01b900460ff1660018111156115cf57634e487b7160e01b600052602160045260246000fd5b146116135760405162461bcd60e51b815260206004820152601460248201527310b4b73234bb34b23ab0b6103932b9b7b63b32b960611b6044820152606401610225565b60125460ff1661164f5760405162461bcd60e51b8152602060048201526007602482015266085b1bd8dad95960ca1b6044820152606401610225565b600c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561169357600080fd5b505afa1580156116a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cb9190612cbd565b9050600081116116ed5760405162461bcd60e51b815260040161022590612eb1565b600b546001600160a01b0316336001600160a01b03161461173c5760405162461bcd60e51b815260206004820152600960248201526810b932b9b7b63b32b960b91b6044820152606401610225565b6000600e548261174c9190612f64565b90506117588183612fa3565b6117628587612f27565b146117af5760405162461bcd60e51b815260206004820152601760248201527f7265736f6c7574696f6e20213d2072656d61696e6465720000000000000000006044820152606401610225565b83156117cb57600c546117cb906001600160a01b031685611ef9565b84156117ee57600954600c546117ee916001600160a01b03918216911687611f64565b801561181157600b54600c54611811916001600160a01b03918216911683611f64565b6010546013556012805460ff19169055604080518681526020810186905280820183905260608101859052905133917f27035e6ed643518ecfca2b08593fd24d4ae4caba6ce5bab683e9b31a12a5b299919081900360800190a2505060018055505050565b60006118826001611984565b9050801561189a576000805461ff0019166101001790555b80156118e1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b50565b600282600681106118f457600080fd5b01816002811061190357600080fd5b602081049091015460ff601f9092166101000a9004169150829050565b6009546001600160a01b0316331461194a5760405162461bcd60e51b815260040161022590612e70565b60095460405130916001600160a01b0316907f78a953f3f0d92abc078a34e5d4fedf8708e788e1b29300b3d6170e97f88a13fc90600090a3565b60008054610100900460ff16156119cb578160ff1660011480156119a75750303b155b6119c35760405162461bcd60e51b815260040161022590612e22565b506000611a05565b60005460ff8084169116106119f25760405162461bcd60e51b815260040161022590612e22565b506000805460ff191660ff831617905560015b919050565b600080808080808080808080611a228c8e018e612a97565b9a509a509a509a509a509a509a509a509a509a509a506000811115611a85576001600160a01b038216611a855760405162461bcd60e51b815260206004820152600b60248201526a696e76616c69642064616f60a81b6044820152606401610225565b6001600160a01b038b16611acc5760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a590818db1a595b9d60921b6044820152606401610225565b600160ff8b161115611b175760405162461bcd60e51b8152602060048201526014602482015273696e76616c6964207265736f6c7665725479706560601b6044820152606401610225565b6001600160a01b038916611b605760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b2103932b9b7b63b32b960811b6044820152606401610225565b6001600160a01b038816611ba65760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610225565b428711611be65760405162461bcd60e51b815260206004820152600e60248201526d191d5c985d1a5bdb88195b99195960921b6044820152606401610225565b611bf46303c30ab042612f27565b871115611c375760405162461bcd60e51b81526020600482015260116024820152706475726174696f6e20746f6f206c6f6e6760781b6044820152606401610225565b6001600160a01b038516611c8d5760405162461bcd60e51b815260206004820152601a60248201527f696e76616c696420777261707065644e6174697665546f6b656e0000000000006044820152606401610225565b604051633aeca7f560e11b81526001600160a01b038a81166004830152600091908516906375d94fea9060240160206040518083038186803b158015611cd257600080fd5b505afa158015611ce6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0a9190612cbd565b905080611d15575060145b600980546001600160a01b0319166001600160a01b038e1617905560ff8b166001811115611d5357634e487b7160e01b600052602160045260246000fd5b600a805460ff60a01b1916600160a01b836001811115611d8357634e487b7160e01b600052602160045260246000fd5b0217905550600b80546001600160a01b03808d166001600160a01b031992831617909255600c80548c8416908316179055600d8a9055600e839055600f899055600880548984169083161790556016805492861692909116919091179055601782905584611e245760095460405130916001600160a01b0316907f78a953f3f0d92abc078a34e5d4fedf8708e788e1b29300b3d6170e97f88a13fc90600090a35b5050505050505050505050505050565b611e3c6129ad565b6040805161010081018252600160c0820181815260e08301829052825282518084018452818152600060208281018290528085019290925284518086018652600380825281840185905285870191909152855180870187528481528084018590526060860152855180870187528481528084019190915260808501528451808601909552845283015260a0810191909152808360068110611eed57634e487b7160e01b600052603260045260246000fd5b60200201519392505050565b6000612710601754830281611f1e57634e487b7160e01b600052601260045260246000fd5b6016549190049150611f3d906001600160a01b03858116911683611f64565b600a54611435906001600160a01b0316611f578385612fa3565b6001600160a01b03861691905b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261143590849061270d565b60125460ff1615611fd95760405162461bcd60e51b815260040161022590612e91565b600d5442116120185760405162461bcd60e51b815260206004820152600b60248201526a085d195c9b5a5b985d195960aa1b6044820152606401610225565b600c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561205c57600080fd5b505afa158015612070573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120949190612cbd565b9050600081116120b65760405162461bcd60e51b815260040161022590612eb1565b600954600c546120d3916001600160a01b03918216911683611f64565b6010546013556040518181527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d906020016118d8565b60125460ff161561212c5760405162461bcd60e51b815260040161022590612e91565b600d54421061216a5760405162461bcd60e51b815260206004820152600a6024820152691d195c9b5a5b985d195960b21b6044820152606401610225565b6009546001600160a01b0316336001600160a01b0316148061219f5750600a546001600160a01b0316336001600160a01b0316145b6121d45760405162461bcd60e51b815260206004820152600660248201526521706172747960d01b6044820152606401610225565b816122215760405162461bcd60e51b815260206004820152601d60248201527f6e6f206d696c6573746f6e657320617265206265696e672061646465640000006044820152606401610225565b600a8211156122725760405162461bcd60e51b815260206004820181905260248201527f6f6e6c79203130206e6577206d696c6573746f6e657320617420612074696d656044820152606401610225565b601054600090612283908490612f27565b905060008167ffffffffffffffff8111156122ae57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156122d7578160200160208202803683370190505b5060115490915060005b601054811015612354576010818154811061230c57634e487b7160e01b600052603260045260246000fd5b906000526020600020015483828151811061233757634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061234c81612fea565b9150506122e1565b506010545b8381101561241557601054879087906123729084612fa3565b81811061238f57634e487b7160e01b600052603260045260246000fd5b905060200201358382815181106123b657634e487b7160e01b600052603260045260246000fd5b6020908102919091010152601054879087906123d29084612fa3565b8181106123ef57634e487b7160e01b600052603260045260246000fd5b90506020020135826124019190612f27565b91508061240d81612fea565b915050612359565b506011819055815161242e9060109060208501906129cb565b50831561247057600f84905560405184815233907f6f6caf08ac16ebd1467ced3e11335ca96f753397f1211110aafea462a3df75929060200160405180910390a25b604051309033907f526d23025be18fff4f70c0855a5d4a85c210a6b4f7d98067aade79c06563667a906124a6908a908a90612d69565b60405180910390a3505050505050565b60125460ff16156124d95760405162461bcd60e51b815260040161022590612e91565b6009546001600160a01b0316336001600160a01b03161461250c5760405162461bcd60e51b815260040161022590612e70565b601354600c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561255357600080fd5b505afa158015612567573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258b9190612cbd565b60105490915082101561269b576000601083815481106125bb57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905060016010805490506125da9190612fa3565b831480156125e757508181105b156125ef5750805b808210156126365760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b6044820152606401610225565b601354612644906001612f27565b601355600c5461265d906001600160a01b031682611ef9565b8060145461266b9190612f27565b601455604080518481526020810183905260008051602061303f833981519152910160405180910390a150611446565b600081116126bb5760405162461bcd60e51b815260040161022590612eb1565b600c546126d1906001600160a01b031682611ef9565b806014546126df9190612f27565b601455604080518381526020810183905260008051602061303f833981519152910160405180910390a15050565b6000612762826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166127df9092919063ffffffff16565b80519091501561143557808060200190518101906127809190612c89565b6114355760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610225565b60606127ee84846000856127f8565b90505b9392505050565b6060824710156128595760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610225565b6001600160a01b0385163b6128b05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610225565b600080866001600160a01b031685876040516128cc9190612d4d565b60006040518083038185875af1925050503d8060008114612909576040519150601f19603f3d011682016040523d82523d6000602084013e61290e565b606091505b509150915061291e828286612929565b979650505050505050565b606083156129385750816127f1565b8251156129485782518084602001fd5b8160405162461bcd60e51b81526004016102259190612e0f565b82805482825590600052602060002090810192821561299d579160200282015b8281111561299d578235825591602001919060010190612982565b506129a9929150612a06565b5090565b60405180604001604052806002906020820280368337509192915050565b82805482825590600052602060002090810192821561299d579160200282015b8281111561299d5782518255916020019190600101906129eb565b5b808211156129a95760008155600101612a07565b8035611a058161301b565b60008083601f840112612a37578182fd5b50813567ffffffffffffffff811115612a4e578182fd5b6020830191508360208260051b8501011115612a6957600080fd5b9250929050565b8035611a0581613030565b600060208284031215612a8c578081fd5b81356127f18161301b565b60008060008060008060008060008060006101608c8e031215612ab8578687fd5b8b35612ac38161301b565b9a5060208c013560ff81168114612ad8578788fd5b995060408c0135612ae88161301b565b9850612af660608d01612a1b565b975060808c0135965060a08c01359550612b1260c08d01612a1b565b9450612b2060e08d01612a70565b9350612b2f6101008d01612a1b565b9250612b3e6101208d01612a1b565b91506101408c013590509295989b509295989b9093969950565b600080600080600060608688031215612b6f578081fd5b8535612b7a8161301b565b9450602086013567ffffffffffffffff80821115612b96578283fd5b612ba289838a01612a26565b90965094506040880135915080821115612bba578283fd5b818801915088601f830112612bcd578283fd5b813581811115612bdb578384fd5b896020828501011115612bec578384fd5b9699959850939650602001949392505050565b60008060208385031215612c11578182fd5b823567ffffffffffffffff811115612c27578283fd5b612c3385828601612a26565b90969095509350505050565b600080600060408486031215612c53578283fd5b833567ffffffffffffffff811115612c69578384fd5b612c7586828701612a26565b909790965060209590950135949350505050565b600060208284031215612c9a578081fd5b81516127f181613030565b600060208284031215612cb6578081fd5b5035919050565b600060208284031215612cce578081fd5b5051919050565b60008060408385031215612ce7578182fd5b50508035926020909101359150565b600080600060608486031215612d0a578283fd5b505081359360208301359350604090920135919050565b60008151808452612d39816020860160208601612fba565b601f01601f19169290920160200192915050565b60008251612d5f818460208701612fba565b9190910192915050565b6020808252810182905260006001600160fb1b03831115612d88578081fd5b8260051b808560408501379190910160400190815292915050565b6020808252825182820181905260009190848201906040850190845b81811015612ddb57835183529284019291840191600101612dbf565b50909695505050505050565b6020810160028310612e0957634e487b7160e01b600052602160045260246000fd5b91905290565b6000602082526127f16020830184612d21565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252600790820152660858db1a595b9d60ca1b604082015260600190565b6020808252600690820152651b1bd8dad95960d21b604082015260600190565b6020808252600c908201526b062616c616e636520697320360a41b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000838252604060208301526127ee6040830184612d21565b60008219821115612f3a57612f3a613005565b500190565b600060ff821660ff84168060ff03821115612f5c57612f5c613005565b019392505050565b600082612f7f57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615612f9e57612f9e613005565b500290565b600082821015612fb557612fb5613005565b500390565b60005b83811015612fd5578181015183820152602001612fbd565b83811115612fe4576000848401525b50505050565b6000600019821415612ffe57612ffe613005565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03811681146118e157600080fd5b80151581146118e157600080fdfe99f6215451102cb496830dfd718a41ae7fb7d92607137ea8961d076bea55c5d3a26469706673582212205c087b319ac26c0cc6dc027fdd9af202de5259fb53344d209668b652c6ab45b564736f6c63430008030033", + "deployedBytecode": "0x6080604052600436106101fd5760003560e01c80635ce6288c1161010d578063a7d07c82116100a0578063e38f48611161006f578063e38f4861146106a6578063e86dad24146106bb578063f51cf927146106d3578063fc0c546a14610705578063fc735e991461072557610338565b8063a7d07c8214610630578063ce4254ce14610650578063cf30901214610666578063dbac78061461069057610338565b806386d1a69f116100dc57806386d1a69f146105cf57806387b0be48146105e4578063946f2e4814610604578063961325211461061a57610338565b80635ce6288c1461054c57806370ff6bd714610561578063786ad4eb1461058f578063868af224146105af57610338565b80632e77c8d2116101905780633d370b4e1161015f5780633d370b4e146104b45780634162169f146104d657806345f0a44f146104f657806349df728c14610516578063565974d31461053657610338565b80632e77c8d214610449578063311a6c561461045f57806337bdc99b1461047f5780633ccfd60b1461049f57610338565b8063109e94cf116101cc578063109e94cf146103cf57806317fcb39b146103ef5780632957b8391461040f5780632ddbd13a1461043357610338565b806301670ba91461033d57806304f3bcec146103525780630721711d1461038f578063085d4883146103af57610338565b366103385760125460ff161561022e5760405162461bcd60e51b815260040161022590612e91565b60405180910390fd5b600854600c546001600160a01b039081169116146102845760405162461bcd60e51b815260206004820152601360248201527210bbb930b83832b22730ba34bb32aa37b5b2b760691b6044820152606401610225565b600860009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156102d457600080fd5b505af11580156102e8573d6000803e3d6000fd5b50505050506102f43390565b6001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405161032e91815260200190565b60405180910390a2005b600080fd5b61035061034b366004612ca5565b61073a565b005b34801561035e57600080fd5b50600b54610372906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561039b57600080fd5b506103506103aa366004612b58565b610a0f565b3480156103bb57600080fd5b50600a54610372906001600160a01b031681565b3480156103db57600080fd5b50600954610372906001600160a01b031681565b3480156103fb57600080fd5b50600854610372906001600160a01b031681565b34801561041b57600080fd5b5061042560175481565b604051908152602001610386565b34801561043f57600080fd5b5061042560115481565b34801561045557600080fd5b5061042560155481565b34801561046b57600080fd5b5061035061047a366004612cd5565b610b59565b34801561048b57600080fd5b5061035061049a366004612ca5565b610ee8565b3480156104ab57600080fd5b50610350611232565b3480156104c057600080fd5b506104c9611268565b6040516103869190612da3565b3480156104e257600080fd5b50601654610372906001600160a01b031681565b34801561050257600080fd5b50610425610511366004612ca5565b6112c0565b34801561052257600080fd5b50610350610531366004612a7b565b6112e1565b34801561054257600080fd5b50610425600f5481565b34801561055857600080fd5b50610425600581565b34801561056d57600080fd5b50600a5461058290600160a01b900460ff1681565b6040516103869190612de7565b34801561059b57600080fd5b506103506105aa366004612c3f565b61142a565b3480156105bb57600080fd5b506103506105ca366004612bff565b61143a565b3480156105db57600080fd5b5061035061144a565b3480156105f057600080fd5b506103506105ff366004612a7b565b61147a565b34801561061057600080fd5b50610425600e5481565b34801561062657600080fd5b5061042560145481565b34801561063c57600080fd5b5061035061064b366004612cf6565b611579565b34801561065c57600080fd5b50610425600d5481565b34801561067257600080fd5b506012546106809060ff1681565b6040519015158152602001610386565b34801561069c57600080fd5b5061042560135481565b3480156106b257600080fd5b50610350611876565b3480156106c757600080fd5b506104256303c30ab081565b3480156106df57600080fd5b506106f36106ee366004612cd5565b6118e4565b60405160ff9091168152602001610386565b34801561071157600080fd5b50600c54610372906001600160a01b031681565b34801561073157600080fd5b50610350611920565b6002600154141561075d5760405162461bcd60e51b815260040161022590612ed7565b600260015560125460ff16156107855760405162461bcd60e51b815260040161022590612e91565b600c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b1580156107c957600080fd5b505afa1580156107dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108019190612cbd565b9050600081116108235760405162461bcd60e51b815260040161022590612eb1565b600d5442106108615760405162461bcd60e51b815260206004820152600a6024820152691d195c9b5a5b985d195960b21b6044820152606401610225565b6009546001600160a01b0316336001600160a01b031614806108965750600a546001600160a01b0316336001600160a01b0316145b6108cb5760405162461bcd60e51b815260206004820152600660248201526521706172747960d01b6044820152606401610225565b6001600a54600160a01b900460ff1660018111156108f957634e487b7160e01b600052602160045260246000fd5b14156109b157600b54600f546040516001600160a01b039092169163c13517e191349160059161092f9160200190815260200190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161095b929190612f0e565b6020604051808303818588803b15801561097457600080fd5b505af1158015610988573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109ad9190612cbd565b6015555b6012805460ff191660011790556109c53390565b6001600160a01b03167fe55f8011a92f4874f2b5795bfe755853e25c72d78f99ce599a78e505178ba240836040516109ff91815260200190565b60405180910390a2505060018055565b6000610a1b6001611984565b90508015610a33576000805461ff0019166101001790555b6001600160a01b038616610a7c5760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b210383937bb34b232b960811b6044820152606401610225565b610a868383611a0a565b600a80546001600160a01b0319166001600160a01b038816179055610aad60108686612962565b506000805b601054811015610b075760108181548110610add57634e487b7160e01b600052603260045260246000fd5b906000526020600020015482610af39190612f27565b915080610aff81612fea565b915050610ab2565b506011558015610b51576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60026001541415610b7c5760405162461bcd60e51b815260040161022590612ed7565b60026001908155600a54600160a01b900460ff166001811115610baf57634e487b7160e01b600052602160045260246000fd5b14610bf35760405162461bcd60e51b815260206004820152601460248201527310b0b93134ba3930ba37b9103932b9b7b63b32b960611b6044820152606401610225565b60125460ff16610c2f5760405162461bcd60e51b8152602060048201526007602482015266085b1bd8dad95960ca1b6044820152606401610225565b600b546001600160a01b0316336001600160a01b031614610c7e5760405162461bcd60e51b815260206004820152600960248201526810b932b9b7b63b32b960b91b6044820152606401610225565b6015548214610cc55760405162461bcd60e51b81526020600482015260136024820152721a5b98dbdc9c9958dd08191a5cdc1d5d195259606a1b6044820152606401610225565b6005811115610d075760405162461bcd60e51b815260206004820152600e60248201526d696e76616c69642072756c696e6760901b6044820152606401610225565b600c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b158015610d4b57600080fd5b505afa158015610d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d839190612cbd565b905060008111610da55760405162461bcd60e51b815260040161022590612eb1565b6000610db083611e34565b80516020820151919250906000610dc78284612f3f565b905060008160ff168360ff1687610dde9190612f84565b610de89190612f64565b90506000610df68288612fa3565b90508115610e1457600c54610e14906001600160a01b031683611ef9565b8015610e3757600954600c54610e37916001600160a01b03918216911683611f64565b6010546013556012805460ff19169055600b5460408051838152602081018590529081018a90526001600160a01b03909116907ff08a08afe8a39853d7db7dd0a42f0cdb68a64ee36a554e68c32219f381e5669e9060600160405180910390a2600b546040518981528a916001600160a01b0316907f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222769060200160405180910390a350506001805550505050505050565b60026001541415610f0b5760405162461bcd60e51b815260040161022590612ed7565b600260015560125460ff1615610f335760405162461bcd60e51b815260040161022590612e91565b6009546001600160a01b0316336001600160a01b031614610f665760405162461bcd60e51b815260040161022590612e70565b601354811015610fab5760405162461bcd60e51b815260206004820152601060248201526f1b5a5b195cdd1bdb99481c185cdcd95960821b6044820152606401610225565b6010548110610ff05760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964206d696c6573746f6e6560781b6044820152606401610225565b600c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561103457600080fd5b505afa158015611048573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106c9190612cbd565b6013549091506000905b8381116111ac5760105461108c90600190612fa3565b811480156110cf575082601082815481106110b757634e487b7160e01b600052603260045260246000fd5b9060005260206000200154836110cd9190612f27565b105b1561110e5760008051602061303f833981519152816110ee8486612fa3565b6040805192835260208301919091520160405180910390a182915061119a565b60008051602061303f833981519152816010838154811061113f57634e487b7160e01b600052603260045260246000fd5b6000918252602091829020015460408051938452918301520160405180910390a16010818154811061118157634e487b7160e01b600052603260045260246000fd5b9060005260206000200154826111979190612f27565b91505b806111a481612fea565b915050611076565b50808210156111f45760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b6044820152606401610225565b600c5461120a906001600160a01b031682611ef9565b806014546112189190612f27565b601455611226836001612f27565b60135550506001805550565b600260015414156112555760405162461bcd60e51b815260040161022590612ed7565b6002600155611262611fb6565b60018055565b606060108054806020026020016040519081016040528092919081815260200182805480156112b657602002820191906000526020600020905b8154815260200190600101908083116112a2575b5050505050905090565b601081815481106112d057600080fd5b600091825260209091200154905081565b600260015414156113045760405162461bcd60e51b815260040161022590612ed7565b6002600155600c546001600160a01b038281169116141561132c57611327611fb6565b611423565b600d54421161136b5760405162461bcd60e51b815260206004820152600b60248201526a085d195c9b5a5b985d195960aa1b6044820152606401610225565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b1580156113ad57600080fd5b505afa1580156113c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e59190612cbd565b9050600081116114075760405162461bcd60e51b815260040161022590612eb1565b600954611421906001600160a01b03848116911683611f64565b505b5060018055565b611435838383612109565b505050565b61144682826000612109565b5050565b6002600154141561146d5760405162461bcd60e51b815260040161022590612ed7565b60026001556112626124b6565b6002600154141561149d5760405162461bcd60e51b815260040161022590612ed7565b6002600155600c546001600160a01b03828116911614156114c0576113276124b6565b6009546001600160a01b0316336001600160a01b0316146114f35760405162461bcd60e51b815260040161022590612e70565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b15801561153557600080fd5b505afa158015611549573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156d9190612cbd565b90506114218282611ef9565b6002600154141561159c5760405162461bcd60e51b815260040161022590612ed7565b60026001556000600a54600160a01b900460ff1660018111156115cf57634e487b7160e01b600052602160045260246000fd5b146116135760405162461bcd60e51b815260206004820152601460248201527310b4b73234bb34b23ab0b6103932b9b7b63b32b960611b6044820152606401610225565b60125460ff1661164f5760405162461bcd60e51b8152602060048201526007602482015266085b1bd8dad95960ca1b6044820152606401610225565b600c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561169357600080fd5b505afa1580156116a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cb9190612cbd565b9050600081116116ed5760405162461bcd60e51b815260040161022590612eb1565b600b546001600160a01b0316336001600160a01b03161461173c5760405162461bcd60e51b815260206004820152600960248201526810b932b9b7b63b32b960b91b6044820152606401610225565b6000600e548261174c9190612f64565b90506117588183612fa3565b6117628587612f27565b146117af5760405162461bcd60e51b815260206004820152601760248201527f7265736f6c7574696f6e20213d2072656d61696e6465720000000000000000006044820152606401610225565b83156117cb57600c546117cb906001600160a01b031685611ef9565b84156117ee57600954600c546117ee916001600160a01b03918216911687611f64565b801561181157600b54600c54611811916001600160a01b03918216911683611f64565b6010546013556012805460ff19169055604080518681526020810186905280820183905260608101859052905133917f27035e6ed643518ecfca2b08593fd24d4ae4caba6ce5bab683e9b31a12a5b299919081900360800190a2505060018055505050565b60006118826001611984565b9050801561189a576000805461ff0019166101001790555b80156118e1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b50565b600282600681106118f457600080fd5b01816002811061190357600080fd5b602081049091015460ff601f9092166101000a9004169150829050565b6009546001600160a01b0316331461194a5760405162461bcd60e51b815260040161022590612e70565b60095460405130916001600160a01b0316907f78a953f3f0d92abc078a34e5d4fedf8708e788e1b29300b3d6170e97f88a13fc90600090a3565b60008054610100900460ff16156119cb578160ff1660011480156119a75750303b155b6119c35760405162461bcd60e51b815260040161022590612e22565b506000611a05565b60005460ff8084169116106119f25760405162461bcd60e51b815260040161022590612e22565b506000805460ff191660ff831617905560015b919050565b600080808080808080808080611a228c8e018e612a97565b9a509a509a509a509a509a509a509a509a509a509a506000811115611a85576001600160a01b038216611a855760405162461bcd60e51b815260206004820152600b60248201526a696e76616c69642064616f60a81b6044820152606401610225565b6001600160a01b038b16611acc5760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a590818db1a595b9d60921b6044820152606401610225565b600160ff8b161115611b175760405162461bcd60e51b8152602060048201526014602482015273696e76616c6964207265736f6c7665725479706560601b6044820152606401610225565b6001600160a01b038916611b605760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b2103932b9b7b63b32b960811b6044820152606401610225565b6001600160a01b038816611ba65760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610225565b428711611be65760405162461bcd60e51b815260206004820152600e60248201526d191d5c985d1a5bdb88195b99195960921b6044820152606401610225565b611bf46303c30ab042612f27565b871115611c375760405162461bcd60e51b81526020600482015260116024820152706475726174696f6e20746f6f206c6f6e6760781b6044820152606401610225565b6001600160a01b038516611c8d5760405162461bcd60e51b815260206004820152601a60248201527f696e76616c696420777261707065644e6174697665546f6b656e0000000000006044820152606401610225565b604051633aeca7f560e11b81526001600160a01b038a81166004830152600091908516906375d94fea9060240160206040518083038186803b158015611cd257600080fd5b505afa158015611ce6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0a9190612cbd565b905080611d15575060145b600980546001600160a01b0319166001600160a01b038e1617905560ff8b166001811115611d5357634e487b7160e01b600052602160045260246000fd5b600a805460ff60a01b1916600160a01b836001811115611d8357634e487b7160e01b600052602160045260246000fd5b0217905550600b80546001600160a01b03808d166001600160a01b031992831617909255600c80548c8416908316179055600d8a9055600e839055600f899055600880548984169083161790556016805492861692909116919091179055601782905584611e245760095460405130916001600160a01b0316907f78a953f3f0d92abc078a34e5d4fedf8708e788e1b29300b3d6170e97f88a13fc90600090a35b5050505050505050505050505050565b611e3c6129ad565b6040805161010081018252600160c0820181815260e08301829052825282518084018452818152600060208281018290528085019290925284518086018652600380825281840185905285870191909152855180870187528481528084018590526060860152855180870187528481528084019190915260808501528451808601909552845283015260a0810191909152808360068110611eed57634e487b7160e01b600052603260045260246000fd5b60200201519392505050565b6000612710601754830281611f1e57634e487b7160e01b600052601260045260246000fd5b6016549190049150611f3d906001600160a01b03858116911683611f64565b600a54611435906001600160a01b0316611f578385612fa3565b6001600160a01b03861691905b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261143590849061270d565b60125460ff1615611fd95760405162461bcd60e51b815260040161022590612e91565b600d5442116120185760405162461bcd60e51b815260206004820152600b60248201526a085d195c9b5a5b985d195960aa1b6044820152606401610225565b600c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561205c57600080fd5b505afa158015612070573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120949190612cbd565b9050600081116120b65760405162461bcd60e51b815260040161022590612eb1565b600954600c546120d3916001600160a01b03918216911683611f64565b6010546013556040518181527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d906020016118d8565b60125460ff161561212c5760405162461bcd60e51b815260040161022590612e91565b600d54421061216a5760405162461bcd60e51b815260206004820152600a6024820152691d195c9b5a5b985d195960b21b6044820152606401610225565b6009546001600160a01b0316336001600160a01b0316148061219f5750600a546001600160a01b0316336001600160a01b0316145b6121d45760405162461bcd60e51b815260206004820152600660248201526521706172747960d01b6044820152606401610225565b816122215760405162461bcd60e51b815260206004820152601d60248201527f6e6f206d696c6573746f6e657320617265206265696e672061646465640000006044820152606401610225565b600a8211156122725760405162461bcd60e51b815260206004820181905260248201527f6f6e6c79203130206e6577206d696c6573746f6e657320617420612074696d656044820152606401610225565b601054600090612283908490612f27565b905060008167ffffffffffffffff8111156122ae57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156122d7578160200160208202803683370190505b5060115490915060005b601054811015612354576010818154811061230c57634e487b7160e01b600052603260045260246000fd5b906000526020600020015483828151811061233757634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061234c81612fea565b9150506122e1565b506010545b8381101561241557601054879087906123729084612fa3565b81811061238f57634e487b7160e01b600052603260045260246000fd5b905060200201358382815181106123b657634e487b7160e01b600052603260045260246000fd5b6020908102919091010152601054879087906123d29084612fa3565b8181106123ef57634e487b7160e01b600052603260045260246000fd5b90506020020135826124019190612f27565b91508061240d81612fea565b915050612359565b506011819055815161242e9060109060208501906129cb565b50831561247057600f84905560405184815233907f6f6caf08ac16ebd1467ced3e11335ca96f753397f1211110aafea462a3df75929060200160405180910390a25b604051309033907f526d23025be18fff4f70c0855a5d4a85c210a6b4f7d98067aade79c06563667a906124a6908a908a90612d69565b60405180910390a3505050505050565b60125460ff16156124d95760405162461bcd60e51b815260040161022590612e91565b6009546001600160a01b0316336001600160a01b03161461250c5760405162461bcd60e51b815260040161022590612e70565b601354600c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561255357600080fd5b505afa158015612567573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258b9190612cbd565b60105490915082101561269b576000601083815481106125bb57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905060016010805490506125da9190612fa3565b831480156125e757508181105b156125ef5750805b808210156126365760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b6044820152606401610225565b601354612644906001612f27565b601355600c5461265d906001600160a01b031682611ef9565b8060145461266b9190612f27565b601455604080518481526020810183905260008051602061303f833981519152910160405180910390a150611446565b600081116126bb5760405162461bcd60e51b815260040161022590612eb1565b600c546126d1906001600160a01b031682611ef9565b806014546126df9190612f27565b601455604080518381526020810183905260008051602061303f833981519152910160405180910390a15050565b6000612762826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166127df9092919063ffffffff16565b80519091501561143557808060200190518101906127809190612c89565b6114355760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610225565b60606127ee84846000856127f8565b90505b9392505050565b6060824710156128595760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610225565b6001600160a01b0385163b6128b05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610225565b600080866001600160a01b031685876040516128cc9190612d4d565b60006040518083038185875af1925050503d8060008114612909576040519150601f19603f3d011682016040523d82523d6000602084013e61290e565b606091505b509150915061291e828286612929565b979650505050505050565b606083156129385750816127f1565b8251156129485782518084602001fd5b8160405162461bcd60e51b81526004016102259190612e0f565b82805482825590600052602060002090810192821561299d579160200282015b8281111561299d578235825591602001919060010190612982565b506129a9929150612a06565b5090565b60405180604001604052806002906020820280368337509192915050565b82805482825590600052602060002090810192821561299d579160200282015b8281111561299d5782518255916020019190600101906129eb565b5b808211156129a95760008155600101612a07565b8035611a058161301b565b60008083601f840112612a37578182fd5b50813567ffffffffffffffff811115612a4e578182fd5b6020830191508360208260051b8501011115612a6957600080fd5b9250929050565b8035611a0581613030565b600060208284031215612a8c578081fd5b81356127f18161301b565b60008060008060008060008060008060006101608c8e031215612ab8578687fd5b8b35612ac38161301b565b9a5060208c013560ff81168114612ad8578788fd5b995060408c0135612ae88161301b565b9850612af660608d01612a1b565b975060808c0135965060a08c01359550612b1260c08d01612a1b565b9450612b2060e08d01612a70565b9350612b2f6101008d01612a1b565b9250612b3e6101208d01612a1b565b91506101408c013590509295989b509295989b9093969950565b600080600080600060608688031215612b6f578081fd5b8535612b7a8161301b565b9450602086013567ffffffffffffffff80821115612b96578283fd5b612ba289838a01612a26565b90965094506040880135915080821115612bba578283fd5b818801915088601f830112612bcd578283fd5b813581811115612bdb578384fd5b896020828501011115612bec578384fd5b9699959850939650602001949392505050565b60008060208385031215612c11578182fd5b823567ffffffffffffffff811115612c27578283fd5b612c3385828601612a26565b90969095509350505050565b600080600060408486031215612c53578283fd5b833567ffffffffffffffff811115612c69578384fd5b612c7586828701612a26565b909790965060209590950135949350505050565b600060208284031215612c9a578081fd5b81516127f181613030565b600060208284031215612cb6578081fd5b5035919050565b600060208284031215612cce578081fd5b5051919050565b60008060408385031215612ce7578182fd5b50508035926020909101359150565b600080600060608486031215612d0a578283fd5b505081359360208301359350604090920135919050565b60008151808452612d39816020860160208601612fba565b601f01601f19169290920160200192915050565b60008251612d5f818460208701612fba565b9190910192915050565b6020808252810182905260006001600160fb1b03831115612d88578081fd5b8260051b808560408501379190910160400190815292915050565b6020808252825182820181905260009190848201906040850190845b81811015612ddb57835183529284019291840191600101612dbf565b50909695505050505050565b6020810160028310612e0957634e487b7160e01b600052602160045260246000fd5b91905290565b6000602082526127f16020830184612d21565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252600790820152660858db1a595b9d60ca1b604082015260600190565b6020808252600690820152651b1bd8dad95960d21b604082015260600190565b6020808252600c908201526b062616c616e636520697320360a41b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000838252604060208301526127ee6040830184612d21565b60008219821115612f3a57612f3a613005565b500190565b600060ff821660ff84168060ff03821115612f5c57612f5c613005565b019392505050565b600082612f7f57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615612f9e57612f9e613005565b500290565b600082821015612fb557612fb5613005565b500390565b60005b83811015612fd5578181015183820152602001612fbd565b83811115612fe4576000848401525b50505050565b6000600019821415612ffe57612ffe613005565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03811681146118e157600080fd5b80151581146118e157600080fdfe99f6215451102cb496830dfd718a41ae7fb7d92607137ea8961d076bea55c5d3a26469706673582212205c087b319ac26c0cc6dc027fdd9af202de5259fb53344d209668b652c6ab45b564736f6c63430008030033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/packages/subgraph/src/mappings/01/factory.ts b/packages/subgraph/src/mappings/01/factory.ts index 629747b5..0faed370 100644 --- a/packages/subgraph/src/mappings/01/factory.ts +++ b/packages/subgraph/src/mappings/01/factory.ts @@ -6,6 +6,7 @@ import { ERC20, SmartInvoiceEscrow01, SmartInvoiceInstant01, + SmartInvoiceSplitEscrow01, } from '../../types/templates'; import { getToken } from './helpers/token'; import { updateInvoice } from './utils'; @@ -40,6 +41,8 @@ export function handleLogNewInvoice(event: LogNewInvoiceEvent): void { if (invoice.invoiceType == 'escrow') { SmartInvoiceEscrow01.create(event.params.invoice); + } else if (invoice.invoiceType == 'split-escrow') { + SmartInvoiceSplitEscrow01.create(event.params.invoice); } else { SmartInvoiceInstant01.create(event.params.invoice); } diff --git a/packages/subgraph/src/mappings/01/helpers/split-escrow.ts b/packages/subgraph/src/mappings/01/helpers/split-escrow.ts new file mode 100644 index 00000000..2ffab945 --- /dev/null +++ b/packages/subgraph/src/mappings/01/helpers/split-escrow.ts @@ -0,0 +1,202 @@ +import { + Address, + BigInt, + Bytes, + ByteArray, + ipfs, + json, + log, +} from '@graphprotocol/graph-ts'; + +import { Invoice, Agreement } from '../../../types/schema'; +import { SmartInvoiceSplitEscrow01 } from '../../../types/templates/SmartInvoiceSplitEscrow01/SmartInvoiceSplitEscrow01'; +import { InvoiceObject, addQm } from '../utils'; + +function fetchSplitEscrowInfo(address: Address): InvoiceObject { + let invoiceInstance = SmartInvoiceSplitEscrow01.bind(address); + + let invoiceObject = new InvoiceObject(); + + let client = invoiceInstance.try_client(); + let provider = invoiceInstance.try_provider(); + let resolverType = invoiceInstance.try_resolverType(); + let resolver = invoiceInstance.try_resolver(); + let resolutionRate = invoiceInstance.try_resolutionRate(); + let token = invoiceInstance.try_token(); + let locked = invoiceInstance.try_locked(); + let milestone = invoiceInstance.try_milestone(); + let total = invoiceInstance.try_total(); + let released = invoiceInstance.try_released(); + let terminationTime = invoiceInstance.try_terminationTime(); + let details = invoiceInstance.try_details(); + let disputeId = invoiceInstance.try_disputeId(); + let dao = invoiceInstance.try_dao(); + let daoFee = invoiceInstance.try_daoFee(); + + if (!client.reverted) { + invoiceObject.client = client.value; + } + if (!provider.reverted) { + invoiceObject.provider = provider.value; + } + if (!resolverType.reverted) { + invoiceObject.resolverType = resolverType.value; + } + if (!resolver.reverted) { + invoiceObject.resolver = resolver.value; + } + if (!resolutionRate.reverted) { + invoiceObject.resolutionRate = resolutionRate.value; + } + if (!token.reverted) { + invoiceObject.token = token.value; + } + if (!locked.reverted) { + invoiceObject.isLocked = locked.value; + } + if (!milestone.reverted) { + invoiceObject.currentMilestone = milestone.value; + } + if (!total.reverted) { + invoiceObject.total = total.value; + } + if (!released.reverted) { + invoiceObject.released = released.value; + } + if (!terminationTime.reverted) { + invoiceObject.terminationTime = terminationTime.value; + } + if (!disputeId.reverted) { + invoiceObject.disputeId = disputeId.value; + } + if (!details.reverted) { + //needs to be broken out based on invoice type + invoiceObject.details = details.value; + if (details.value.length == 32) { + let hexHash = changetype(addQm(invoiceObject.details)); + let base58Hash = hexHash.toBase58(); + invoiceObject.ipfsHash = base58Hash.toString(); + let ipfsData = ipfs.cat(base58Hash); + if (ipfsData !== null) { + log.info('IPFS details from hash {}, data {}', [ + base58Hash, + ipfsData.toString(), + ]); + let data = json.fromBytes(ipfsData).toObject(); + let projectName = data.get('projectName'); + if (projectName != null && !projectName.isNull()) { + invoiceObject.projectName = projectName.toString(); + } + let projectDescription = data.get('projectDescription'); + if (projectDescription != null && !projectDescription.isNull()) { + invoiceObject.projectDescription = projectDescription.toString(); + } + let projectAgreement = data.get('projectAgreement'); + if (projectAgreement != null && !projectAgreement.isNull()) { + let projectArray = projectAgreement.toArray(); + let agreementArray = new Array(); + + for (let i = 0; i < projectArray.length; i++) { + let obj = projectArray[i].toObject(); + let type = obj.get('type'); + let src = obj.get('src'); + let createdAt = obj.get('createdAt'); + if (type && src && createdAt != null) { + let typeValue = type.toString(); + let srcValue = src.toString(); + let createdAtValue = BigInt.fromString(createdAt.toString()); + + let agreement = new Agreement(createdAtValue.toString()); + + agreement.type = typeValue; + agreement.src = srcValue; + agreement.createdAt = createdAtValue; + + log.info( + 'agreement commit: agreement.type {} agreement.src {} agreement.createdAt {} index {}', + [ + agreement.type, + agreement.src, + agreement.createdAt.toString(), + i.toString(), + ], + ); + + agreement.save(); + + agreementArray[i] = agreement; + } + } + + invoiceObject.projectAgreement = agreementArray; + } + let startDate = data.get('startDate'); + if (startDate != null && !startDate.isNull()) { + invoiceObject.startDate = startDate.toBigInt(); + } + let endDate = data.get('endDate'); + if (endDate != null && !endDate.isNull()) { + invoiceObject.endDate = endDate.toBigInt(); + } + } else { + log.warning('could not get IPFS details from hash {}', [base58Hash]); + } + } + } + if (!dao.reverted) { + invoiceObject.dao = dao.value; + } + if (!daoFee.reverted) { + invoiceObject.daoFee = daoFee.value; + } + + return invoiceObject; +} + +export function updateSplitEscrowInfo( + address: Address, + invoice: Invoice, +): Invoice { + let invoiceObject = fetchSplitEscrowInfo(address); + + log.info('Got details for invoice', [address.toHexString()]); + + invoice.token = invoiceObject.token; + invoice.client = invoiceObject.client; + invoice.provider = invoiceObject.provider; + if (invoiceObject.resolverType == 0) { + invoice.resolverType = 'individual'; + } else if (invoiceObject.resolverType == 1) { + invoice.resolverType = 'arbitrator'; + } + invoice.resolver = invoiceObject.resolver; + invoice.resolutionRate = invoiceObject.resolutionRate; + invoice.isLocked = invoiceObject.isLocked; + invoice.currentMilestone = invoiceObject.currentMilestone; + invoice.total = invoiceObject.total; + invoice.released = invoiceObject.released; + invoice.terminationTime = invoiceObject.terminationTime; + invoice.details = invoiceObject.details; + invoice.ipfsHash = invoiceObject.ipfsHash; + invoice.disputeId = invoiceObject.disputeId; + invoice.projectName = invoiceObject.projectName; + invoice.projectDescription = invoiceObject.projectDescription; + invoice.startDate = invoiceObject.startDate; + invoice.endDate = invoiceObject.endDate; + invoice.dao = invoiceObject.dao; + invoice.daoFee = invoiceObject.daoFee; + + invoice.projectAgreement.length = 0; + let projectAgreement = new Array(); + let sourceAgreements = invoiceObject.projectAgreement; + + for (let i = 0; i < sourceAgreements.length; i++) { + projectAgreement[i] = sourceAgreements[i].id; + } + + invoice.projectAgreement = projectAgreement; + + log.info('fox tango {}', [invoice.projectName.toString()]); + + return invoice as Invoice; +} diff --git a/packages/subgraph/src/mappings/01/utils.ts b/packages/subgraph/src/mappings/01/utils.ts index 1d00899b..07972fc4 100644 --- a/packages/subgraph/src/mappings/01/utils.ts +++ b/packages/subgraph/src/mappings/01/utils.ts @@ -12,6 +12,7 @@ import { Agreement, Invoice } from '../../types/schema'; import { updateEscrowInfo } from './helpers/escrow'; import { updateInstantInfo } from './helpers/instant'; +import { updateSplitEscrowInfo } from './helpers/split-escrow'; let zeroAddress = changetype
( Address.fromHexString('0x0000000000000000000000000000000000000000'), @@ -46,6 +47,8 @@ export class InvoiceObject { // tipAmount: Array; deadline: BigInt; fulfilled: boolean; + dao: Address; + daoFee: BigInt; constructor() { this.client = zeroAddress; @@ -74,6 +77,8 @@ export class InvoiceObject { // this.tipAmount = new Array(); this.deadline = BigInt.fromI32(0); this.fulfilled = false; + this.dao = zeroAddress; + this.daoFee = BigInt.fromI32(0); } } @@ -93,6 +98,8 @@ export function updateInvoice(address: Address, invoice: Invoice): Invoice { if (type != null) { if (type == 'escrow') { invoice = updateEscrowInfo(address, invoice); + } else if (type == 'split-escrow') { + invoice = updateSplitEscrowInfo(address, invoice); } else { invoice = updateInstantInfo(address, invoice); } diff --git a/packages/subgraph/src/schema.graphql b/packages/subgraph/src/schema.graphql index 8dab1309..07307166 100644 --- a/packages/subgraph/src/schema.graphql +++ b/packages/subgraph/src/schema.graphql @@ -45,6 +45,9 @@ type Invoice @entity { tipAmount: [Tip!] deadline: BigInt fulfilled: Boolean + # split-escrow type specific + dao: Bytes + daoFee: BigInt } enum ADR @entity { diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml index 4f4d0991..a1fdf813 100644 --- a/packages/subgraph/subgraph.template.yaml +++ b/packages/subgraph/subgraph.template.yaml @@ -167,6 +167,47 @@ templates: - event: Fulfilled(indexed address) handler: handleFulfilled file: ./src/mappings/{{factoryName}}/invoice.ts + - kind: ethereum/contract + name: SmartInvoiceSplitEscrow{{factoryName}} + # prettier-ignore + network: {{network}} + source: + abi: SmartInvoiceSplitEscrow{{factoryName}} + mapping: + kind: ethereum/events + apiVersion: 0.0.6 + language: wasm/assemblyscript + entities: + - Invoice + - Release + - Deposit + - Resolution + - Token + abis: + - name: ERC20 + file: ./src/abis/ERC20.json + - name: SmartInvoiceSplitEscrow{{factoryName}} + file: ./src/abis/{{factoryName}}/SmartInvoiceSplitEscrow{{factoryName}}.json + - name: SmartInvoiceFactory{{factoryName}} + file: ./src/abis/{{factoryName}}/SmartInvoiceFactory{{factoryName}}.json + eventHandlers: + - event: Release(uint256,uint256) + handler: handleRelease + - event: Withdraw(uint256) + handler: handleWithdraw + - event: Lock(indexed address,bytes32) + handler: handleLock + - event: Rule(indexed address,uint256,uint256,uint256) + handler: handleRule + - event: Resolve(indexed address,uint256,uint256,uint256,bytes32) + handler: handleResolve + - event: Deposit(indexed address,uint256) + handler: handleDeposit + - event: Verified(indexed address,indexed address) + handler: handleVerified + - event: MilestonesAdded(indexed address,indexed address,uint256[]) + handler: handleMilestonesAdded + file: ./src/mappings/{{factoryName}}/invoice.ts {{/v01}} {{/factories}} - kind: ethereum/contract diff --git a/packages/subgraph/subgraph.yaml b/packages/subgraph/subgraph.yaml index d5534044..0b24dc99 100644 --- a/packages/subgraph/subgraph.yaml +++ b/packages/subgraph/subgraph.yaml @@ -176,6 +176,47 @@ templates: - event: Fulfilled(indexed address) handler: handleFulfilled file: ./src/mappings/01/invoice.ts + - kind: ethereum/contract + name: SmartInvoiceSplitEscrow01 + # prettier-ignore + network: mainnet + source: + abi: SmartInvoiceSplitEscrow01 + mapping: + kind: ethereum/events + apiVersion: 0.0.6 + language: wasm/assemblyscript + entities: + - Invoice + - Release + - Deposit + - Resolution + - Token + abis: + - name: ERC20 + file: ./src/abis/ERC20.json + - name: SmartInvoiceSplitEscrow01 + file: ./src/abis/01/SmartInvoiceSplitEscrow01.json + - name: SmartInvoiceFactory01 + file: ./src/abis/01/SmartInvoiceFactory01.json + eventHandlers: + - event: Release(uint256,uint256) + handler: handleRelease + - event: Withdraw(uint256) + handler: handleWithdraw + - event: Lock(indexed address,bytes32) + handler: handleLock + - event: Rule(indexed address,uint256,uint256,uint256) + handler: handleRule + - event: Resolve(indexed address,uint256,uint256,uint256,bytes32) + handler: handleResolve + - event: Deposit(indexed address,uint256) + handler: handleDeposit + - event: Verified(indexed address,indexed address) + handler: handleVerified + - event: MilestonesAdded(indexed address,indexed address,uint256[]) + handler: handleMilestonesAdded + file: ./src/mappings/01/invoice.ts - kind: ethereum/contract name: ERC20 # prettier-ignore @@ -200,6 +241,8 @@ templates: file: ./src/abis/01/SmartInvoiceEscrow01.json - name: SmartInvoiceInstant01 file: ./src/abis/01/SmartInvoiceInstant01.json + - name: SmartInvoiceSplitEscrow01 + file: ./src/abis/01/SmartInvoiceSplitEscrow01.json - name: SmartInvoiceFactory01 file: ./src/abis/01/SmartInvoiceFactory01.json eventHandlers: From bbb8db04617b3abadf25657ea7b3bfd8edaf17a1 Mon Sep 17 00:00:00 2001 From: geovgy Date: Wed, 23 Aug 2023 12:32:53 -0400 Subject: [PATCH 2/8] Modify mappings, abi and yaml; testing on goerli --- packages/dapp/constants/config.js | 2 +- .../subgraph/manifests/goerli.subgraph.yaml | 45 ++++++++++++++++++- packages/subgraph/package.json | 2 +- .../abis/01/SmartInvoiceSplitEscrow01.json | 2 +- packages/subgraph/src/mappings/00/factory.ts | 2 +- packages/subgraph/src/mappings/01/factory.ts | 2 +- packages/subgraph/subgraph.yaml | 24 +++++----- 7 files changed, 60 insertions(+), 19 deletions(-) diff --git a/packages/dapp/constants/config.js b/packages/dapp/constants/config.js index 271e09b1..b3d33ebe 100644 --- a/packages/dapp/constants/config.js +++ b/packages/dapp/constants/config.js @@ -51,7 +51,7 @@ export const CONFIG = { }, }, 5: { - SUBGRAPH: 'psparacino/goerli-smart-invoices', + SUBGRAPH: 'geovgy/v1-goerli-smart-invoice', // previously: psparacino/goerli-smart-invoices WRAPPED_NATIVE_TOKEN: '0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6'.toLowerCase(), INVOICE_FACTORY: diff --git a/packages/subgraph/manifests/goerli.subgraph.yaml b/packages/subgraph/manifests/goerli.subgraph.yaml index db82a646..2c03192e 100644 --- a/packages/subgraph/manifests/goerli.subgraph.yaml +++ b/packages/subgraph/manifests/goerli.subgraph.yaml @@ -177,6 +177,47 @@ templates: - event: Tip(indexed address,uint256) handler: handleDeposit file: ./src/mappings/01/invoice.ts + - kind: ethereum/contract + name: SmartInvoiceSplitEscrow01 + # prettier-ignore + network: goerli + source: + abi: SmartInvoiceSplitEscrow01 + mapping: + kind: ethereum/events + apiVersion: 0.0.6 + language: wasm/assemblyscript + entities: + - Invoice + - Release + - Deposit + - Resolution + - Token + abis: + - name: ERC20 + file: ./src/abis/ERC20.json + - name: SmartInvoiceSplitEscrow01 + file: ./src/abis/01/SmartInvoiceSplitEscrow01.json + - name: SmartInvoiceFactory01 + file: ./src/abis/01/SmartInvoiceFactory01.json + eventHandlers: + - event: Release(uint256,uint256) + handler: handleRelease + - event: Withdraw(uint256) + handler: handleWithdraw + - event: Lock(indexed address,bytes32) + handler: handleLock + - event: Rule(indexed address,uint256,uint256,uint256) + handler: handleRule + - event: Resolve(indexed address,uint256,uint256,uint256,bytes32) + handler: handleResolve + - event: Deposit(indexed address,uint256) + handler: handleDeposit + - event: Verified(indexed address,indexed address) + handler: handleVerified + - event: MilestonesAdded(indexed address,indexed address,uint256[]) + handler: handleMilestonesAdded + file: ./src/mappings/01/invoice.ts - kind: ethereum/contract name: ERC20 # prettier-ignore @@ -199,7 +240,9 @@ templates: file: ./src/abis/00/SmartInvoiceFactory00.json - name: SmartInvoiceEscrow01 file: ./src/abis/01/SmartInvoiceEscrow01.json - - name: SmartInvoiceFactory + - name: SmartInvoiceSplitEscrow01 + file: ./src/abis/01/SmartInvoiceSplitEscrow01.json + - name: SmartInvoiceFactory01 file: ./src/abis/01/SmartInvoiceFactory01.json eventHandlers: - event: Transfer(indexed address,indexed address,uint256) diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json index d85c4fbf..a0b86a32 100644 --- a/packages/subgraph/package.json +++ b/packages/subgraph/package.json @@ -18,7 +18,7 @@ "dev-deploy-only-rinkey": "yarn prepare-rinkeby && yarn codegen && yarn build && graph deploy psparacino/smart-invoices-rinkey-ps --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/ --debug", "deploy-only-gnosis": "graph deploy psparacino/v1-xdai-smart-invoices --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/ --debug", "deploy-only-mainnet": "graph deploy --product hosted-service psparacino/v1-mainnet-smart-invoices --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/ --debug", - "deploy-only-goerli": "graph deploy --product hosted-service psparacino/goerli-smart-invoices --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/ --debug", + "deploy-only-goerli": "graph deploy --product hosted-service geovgy/v1-goerli-smart-invoice --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/ --debug", "deploy-only-mumbai": "graph deploy --product hosted-service psparacino/v1-mumbai-smart-invoices --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/ --debug", "deploy-rinkeby": "yarn prepare-rinkeby && yarn codegen && yarn build && yarn deploy-only-rinkeby", "deploy-mumbai": "yarn prepare-mumbai && yarn codegen && yarn build && yarn deploy-only-mumbai", diff --git a/packages/subgraph/src/abis/01/SmartInvoiceSplitEscrow01.json b/packages/subgraph/src/abis/01/SmartInvoiceSplitEscrow01.json index fb3e20a7..56995904 100644 --- a/packages/subgraph/src/abis/01/SmartInvoiceSplitEscrow01.json +++ b/packages/subgraph/src/abis/01/SmartInvoiceSplitEscrow01.json @@ -1,6 +1,6 @@ { "_format": "hh-sol-artifact-1", - "contractName": "SmartInvoiceSplitEscrow", + "contractName": "SmartInvoiceSplitEscrow01", "sourceName": "contracts/SmartInvoiceSplitEscrow.sol", "abi": [ { diff --git a/packages/subgraph/src/mappings/00/factory.ts b/packages/subgraph/src/mappings/00/factory.ts index dbbe87ab..3bacac8d 100644 --- a/packages/subgraph/src/mappings/00/factory.ts +++ b/packages/subgraph/src/mappings/00/factory.ts @@ -1,7 +1,7 @@ import { log, dataSource, Address, Bytes } from '@graphprotocol/graph-ts'; import { Invoice, Agreement } from '../../types/schema'; -import { LogNewInvoice as LogNewInvoiceEvent } from '../../types/SmartInvoiceFactoryVersion00/SmartInvoiceFactory00'; +import { LogNewInvoice as LogNewInvoiceEvent } from '../../types/SmartInvoiceFactory00/SmartInvoiceFactory00'; import { ERC20, SmartInvoice00 } from '../../types/templates'; import { updateInvoiceInfo, getToken } from './helpers'; diff --git a/packages/subgraph/src/mappings/01/factory.ts b/packages/subgraph/src/mappings/01/factory.ts index 0faed370..80caa12a 100644 --- a/packages/subgraph/src/mappings/01/factory.ts +++ b/packages/subgraph/src/mappings/01/factory.ts @@ -1,7 +1,7 @@ import { log, dataSource, Address, Bytes } from '@graphprotocol/graph-ts'; import { Invoice, Agreement } from '../../types/schema'; -import { LogNewInvoice as LogNewInvoiceEvent } from '../../types/SmartInvoiceFactoryVersion01/SmartInvoiceFactory01'; +import { LogNewInvoice as LogNewInvoiceEvent } from '../../types/SmartInvoiceFactory01/SmartInvoiceFactory01'; import { ERC20, SmartInvoiceEscrow01, diff --git a/packages/subgraph/subgraph.yaml b/packages/subgraph/subgraph.yaml index 0b24dc99..accf2c95 100644 --- a/packages/subgraph/subgraph.yaml +++ b/packages/subgraph/subgraph.yaml @@ -8,12 +8,12 @@ dataSources: - kind: ethereum/contract name: SmartInvoiceFactory00 # prettier-ignore - network: mainnet + network: goerli source: - address: '0xe73251284989c4496985f16c718369bbc30ccf63' + address: '0x566ac8344a7cbBC4879e5692F32A9ebdED002e7f' abi: SmartInvoiceFactory00 # prettier-ignore - startBlock: 15546992 + startBlock: 9556965 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -35,12 +35,12 @@ dataSources: - kind: ethereum/contract name: SmartInvoiceFactory01 # prettier-ignore - network: mainnet + network: goerli source: - address: '0x5E14cF595e18F91170009946205f8BBa21b323ca' + address: '0x546adED0B0179d550e87cf909939a1207Fd26fB7' abi: SmartInvoiceFactory01 # prettier-ignore - startBlock: 16991083 + startBlock: 9556965 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -65,7 +65,7 @@ templates: - kind: ethereum/contract name: SmartInvoice00 # prettier-ignore - network: mainnet + network: goerli source: abi: SmartInvoice00 mapping: @@ -106,7 +106,7 @@ templates: - kind: ethereum/contract name: SmartInvoiceEscrow01 # prettier-ignore - network: mainnet + network: goerli source: abi: SmartInvoiceEscrow01 mapping: @@ -147,7 +147,7 @@ templates: - kind: ethereum/contract name: SmartInvoiceInstant01 # prettier-ignore - network: mainnet + network: goerli source: abi: SmartInvoiceInstant01 mapping: @@ -179,7 +179,7 @@ templates: - kind: ethereum/contract name: SmartInvoiceSplitEscrow01 # prettier-ignore - network: mainnet + network: goerli source: abi: SmartInvoiceSplitEscrow01 mapping: @@ -220,7 +220,7 @@ templates: - kind: ethereum/contract name: ERC20 # prettier-ignore - network: mainnet + network: goerli source: abi: ERC20 mapping: @@ -241,8 +241,6 @@ templates: file: ./src/abis/01/SmartInvoiceEscrow01.json - name: SmartInvoiceInstant01 file: ./src/abis/01/SmartInvoiceInstant01.json - - name: SmartInvoiceSplitEscrow01 - file: ./src/abis/01/SmartInvoiceSplitEscrow01.json - name: SmartInvoiceFactory01 file: ./src/abis/01/SmartInvoiceFactory01.json eventHandlers: From 2d35c507fc35e4dc2a215ad2b6778b0b41b41156 Mon Sep 17 00:00:00 2001 From: geovgy Date: Fri, 25 Aug 2023 12:04:20 -0400 Subject: [PATCH 3/8] Add missing ABI mappings --- packages/subgraph/manifests/goerli.subgraph.yaml | 2 ++ packages/subgraph/subgraph.template.yaml | 4 ++++ packages/subgraph/subgraph.yaml | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/packages/subgraph/manifests/goerli.subgraph.yaml b/packages/subgraph/manifests/goerli.subgraph.yaml index 2c03192e..21f16fae 100644 --- a/packages/subgraph/manifests/goerli.subgraph.yaml +++ b/packages/subgraph/manifests/goerli.subgraph.yaml @@ -57,6 +57,8 @@ dataSources: file: ./src/abis/01/SmartInvoiceEscrow01.json - name: SmartInvoiceInstant01 file: ./src/abis/01/SmartInvoiceInstant01.json + - name: SmartInvoiceSplitEscrow01 + file: ./src/abis/01/SmartInvoiceSplitEscrow01.json - name: SmartInvoiceFactory01 file: ./src/abis/01/SmartInvoiceFactory01.json eventHandlers: diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml index a1fdf813..f31734b8 100644 --- a/packages/subgraph/subgraph.template.yaml +++ b/packages/subgraph/subgraph.template.yaml @@ -33,6 +33,8 @@ dataSources: file: ./src/abis/{{factoryName}}/SmartInvoiceEscrow{{factoryName}}.json - name: SmartInvoiceInstant{{factoryName}} file: ./src/abis/{{factoryName}}/SmartInvoiceInstant{{factoryName}}.json + - name: SmartInvoiceSplitEscrow{{factoryName}} + file: ./src/abis/{{factoryName}}/SmartInvoiceSplitEscrow{{factoryName}}.json {{/v01}} - name: SmartInvoiceFactory{{factoryName}} file: ./src/abis/{{factoryName}}/SmartInvoiceFactory{{factoryName}}.json @@ -238,6 +240,8 @@ templates: file: ./src/abis/{{factoryName}}/SmartInvoiceEscrow{{factoryName}}.json - name: SmartInvoiceInstant{{factoryName}} file: ./src/abis/{{factoryName}}/SmartInvoiceInstant{{factoryName}}.json + - name: SmartInvoiceSplitEscrow{{factoryName}} + file: ./src/abis/{{factoryName}}/SmartInvoiceSplitEscrow{{factoryName}}.json - name: SmartInvoiceFactory{{factoryName}} file: ./src/abis/{{factoryName}}/SmartInvoiceFactory{{factoryName}}.json {{/v01}} diff --git a/packages/subgraph/subgraph.yaml b/packages/subgraph/subgraph.yaml index accf2c95..a4a5e41f 100644 --- a/packages/subgraph/subgraph.yaml +++ b/packages/subgraph/subgraph.yaml @@ -54,6 +54,8 @@ dataSources: file: ./src/abis/01/SmartInvoiceEscrow01.json - name: SmartInvoiceInstant01 file: ./src/abis/01/SmartInvoiceInstant01.json + - name: SmartInvoiceSplitEscrow01 + file: ./src/abis/01/SmartInvoiceSplitEscrow01.json - name: SmartInvoiceFactory01 file: ./src/abis/01/SmartInvoiceFactory01.json eventHandlers: @@ -241,6 +243,8 @@ templates: file: ./src/abis/01/SmartInvoiceEscrow01.json - name: SmartInvoiceInstant01 file: ./src/abis/01/SmartInvoiceInstant01.json + - name: SmartInvoiceSplitEscrow01 + file: ./src/abis/01/SmartInvoiceSplitEscrow01.json - name: SmartInvoiceFactory01 file: ./src/abis/01/SmartInvoiceFactory01.json eventHandlers: From f0c2554f358ad026d3a7989f63047b1e3e9c9c8d Mon Sep 17 00:00:00 2001 From: scottrepreneur Date: Sun, 10 Dec 2023 08:48:35 -0600 Subject: [PATCH 4/8] updatable receiver subgraph --- .../contracts/SmartInvoiceUpdatable.sol | 7 + .../src/abis/01/SmartInvoiceUpdatable01.json | 736 ++++++++++++++++++ packages/subgraph/src/mappings/01/factory.ts | 3 + .../src/mappings/01/helpers/escrow.ts | 87 +-- .../subgraph/src/mappings/01/helpers/ipfs.ts | 99 +++ .../src/mappings/01/helpers/split-escrow.ts | 87 +-- .../mappings/01/helpers/updatable-escrow.ts | 122 +++ packages/subgraph/src/mappings/01/utils.ts | 15 +- packages/subgraph/src/schema.graphql | 5 +- packages/subgraph/subgraph.template.yaml | 49 ++ packages/subgraph/subgraph.yaml | 84 +- 11 files changed, 1096 insertions(+), 198 deletions(-) create mode 100644 packages/subgraph/src/abis/01/SmartInvoiceUpdatable01.json create mode 100644 packages/subgraph/src/mappings/01/helpers/ipfs.ts create mode 100644 packages/subgraph/src/mappings/01/helpers/updatable-escrow.ts diff --git a/packages/contracts/contracts/SmartInvoiceUpdatable.sol b/packages/contracts/contracts/SmartInvoiceUpdatable.sol index 0df9a53d..40c29cd0 100644 --- a/packages/contracts/contracts/SmartInvoiceUpdatable.sol +++ b/packages/contracts/contracts/SmartInvoiceUpdatable.sol @@ -14,6 +14,10 @@ contract SmartInvoiceUpdatable is SmartInvoiceEscrow { /// @notice The receiving address for the provider address public providerReceiver; + event UpdatedClient(address indexed client); + event UpdatedProvider(address indexed provider); + event UpdatedProviderReceiver(address indexed providerReceiver); + /** * Modifier for functions that can only be called by the provider */ @@ -36,6 +40,7 @@ contract SmartInvoiceUpdatable is SmartInvoiceEscrow { */ function _updateClient(address _client) internal { client = _client; + emit UpdatedClient(_client); } /** @@ -53,6 +58,7 @@ contract SmartInvoiceUpdatable is SmartInvoiceEscrow { */ function _updateProviderReceiver(address _providerReceiver) internal { providerReceiver = _providerReceiver; + emit UpdatedProviderReceiver(_providerReceiver); } /** @@ -72,6 +78,7 @@ contract SmartInvoiceUpdatable is SmartInvoiceEscrow { */ function _updateProvider(address _provider) internal { provider = _provider; + emit UpdatedProvider(_provider); } /** diff --git a/packages/subgraph/src/abis/01/SmartInvoiceUpdatable01.json b/packages/subgraph/src/abis/01/SmartInvoiceUpdatable01.json new file mode 100644 index 00000000..8f71b289 --- /dev/null +++ b/packages/subgraph/src/abis/01/SmartInvoiceUpdatable01.json @@ -0,0 +1,736 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "details", + "type": "bytes32" + } + ], + "name": "DetailsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "details", + "type": "bytes32" + } + ], + "name": "Lock", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "invoice", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "milestones", + "type": "uint256[]" + } + ], + "name": "MilestonesAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "milestone", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Release", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "resolver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "clientAward", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "providerAward", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "resolutionFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "details", + "type": "bytes32" + } + ], + "name": "Resolve", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "resolver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "clientAward", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "providerAward", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ruling", + "type": "uint256" + } + ], + "name": "Rule", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_arbitrator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_disputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "Ruling", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "client", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "invoice", + "type": "address" + } + ], + "name": "Verified", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_TERMINATION_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NUM_RULING_OPTIONS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "RULINGS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_milestones", + "type": "uint256[]" + }, + { + "internalType": "bytes32", + "name": "_details", + "type": "bytes32" + } + ], + "name": "addMilestones", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_milestones", + "type": "uint256[]" + } + ], + "name": "addMilestones", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "amounts", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "client", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "details", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disputeId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAmounts", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "_amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initLock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_details", + "type": "bytes32" + } + ], + "name": "lock", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "locked", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "milestone", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "provider", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "providerReceiver", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_milestone", + "type": "uint256" + } + ], + "name": "release", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "release", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "releaseTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "released", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "resolutionRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_clientAward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_providerAward", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_details", + "type": "bytes32" + } + ], + "name": "resolve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resolver", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "resolverType", + "outputs": [ + { + "internalType": "enum SmartInvoiceEscrow.ADR", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_disputeId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_ruling", + "type": "uint256" + } + ], + "name": "rule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "terminationTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "total", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_client", + "type": "address" + } + ], + "name": "updateClient", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_provider", + "type": "address" + } + ], + "name": "updateProvider", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_providerReceiver", + "type": "address" + } + ], + "name": "updateProviderReceiver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "verify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "withdrawTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "wrappedNativeToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/packages/subgraph/src/mappings/01/factory.ts b/packages/subgraph/src/mappings/01/factory.ts index 80caa12a..0a738170 100644 --- a/packages/subgraph/src/mappings/01/factory.ts +++ b/packages/subgraph/src/mappings/01/factory.ts @@ -7,6 +7,7 @@ import { SmartInvoiceEscrow01, SmartInvoiceInstant01, SmartInvoiceSplitEscrow01, + SmartInvoiceUpdatable01, } from '../../types/templates'; import { getToken } from './helpers/token'; import { updateInvoice } from './utils'; @@ -43,6 +44,8 @@ export function handleLogNewInvoice(event: LogNewInvoiceEvent): void { SmartInvoiceEscrow01.create(event.params.invoice); } else if (invoice.invoiceType == 'split-escrow') { SmartInvoiceSplitEscrow01.create(event.params.invoice); + } else if (invoice.invoiceType == 'updatable') { + SmartInvoiceUpdatable01.create(event.params.invoice); } else { SmartInvoiceInstant01.create(event.params.invoice); } diff --git a/packages/subgraph/src/mappings/01/helpers/escrow.ts b/packages/subgraph/src/mappings/01/helpers/escrow.ts index 4a214ab3..6ed597cd 100644 --- a/packages/subgraph/src/mappings/01/helpers/escrow.ts +++ b/packages/subgraph/src/mappings/01/helpers/escrow.ts @@ -1,16 +1,9 @@ -import { - Address, - BigInt, - Bytes, - ByteArray, - ipfs, - json, - log, -} from '@graphprotocol/graph-ts'; +import { Address, log } from '@graphprotocol/graph-ts'; -import { Invoice, Agreement } from '../../../types/schema'; +import { Invoice } from '../../../types/schema'; import { SmartInvoiceEscrow01 } from '../../../types/templates/SmartInvoiceEscrow01/SmartInvoiceEscrow01'; -import { InvoiceObject, addQm } from '../utils'; +import { InvoiceObject } from '../utils'; +import { handleIpfsDetails } from './ipfs'; function fetchEscrowInfo(address: Address): InvoiceObject { let invoiceInstance = SmartInvoiceEscrow01.bind(address); @@ -69,77 +62,7 @@ function fetchEscrowInfo(address: Address): InvoiceObject { } if (!details.reverted) { //needs to be broken out based on invoice type - invoiceObject.details = details.value; - if (details.value.length == 32) { - let hexHash = changetype(addQm(invoiceObject.details)); - let base58Hash = hexHash.toBase58(); - invoiceObject.ipfsHash = base58Hash.toString(); - let ipfsData = ipfs.cat(base58Hash); - if (ipfsData !== null) { - log.info('IPFS details from hash {}, data {}', [ - base58Hash, - ipfsData.toString(), - ]); - let data = json.fromBytes(ipfsData).toObject(); - let projectName = data.get('projectName'); - if (projectName != null && !projectName.isNull()) { - invoiceObject.projectName = projectName.toString(); - } - let projectDescription = data.get('projectDescription'); - if (projectDescription != null && !projectDescription.isNull()) { - invoiceObject.projectDescription = projectDescription.toString(); - } - let projectAgreement = data.get('projectAgreement'); - if (projectAgreement != null && !projectAgreement.isNull()) { - let projectArray = projectAgreement.toArray(); - let agreementArray = new Array(); - - for (let i = 0; i < projectArray.length; i++) { - let obj = projectArray[i].toObject(); - let type = obj.get('type'); - let src = obj.get('src'); - let createdAt = obj.get('createdAt'); - if (type && src && createdAt != null) { - let typeValue = type.toString(); - let srcValue = src.toString(); - let createdAtValue = BigInt.fromString(createdAt.toString()); - - let agreement = new Agreement(createdAtValue.toString()); - - agreement.type = typeValue; - agreement.src = srcValue; - agreement.createdAt = createdAtValue; - - log.info( - 'agreement commit: agreement.type {} agreement.src {} agreement.createdAt {} index {}', - [ - agreement.type, - agreement.src, - agreement.createdAt.toString(), - i.toString(), - ], - ); - - agreement.save(); - - agreementArray[i] = agreement; - } - } - - invoiceObject.projectAgreement = agreementArray; - } - let startDate = data.get('startDate'); - if (startDate != null && !startDate.isNull()) { - invoiceObject.startDate = startDate.toBigInt(); - } - let endDate = data.get('endDate'); - if (endDate != null && !endDate.isNull()) { - invoiceObject.endDate = endDate.toBigInt(); - } - } else { - log.warning('could not get IPFS details from hash {}', [base58Hash]); - } - } + invoiceObject = handleIpfsDetails(details.value, invoiceObject); } return invoiceObject; diff --git a/packages/subgraph/src/mappings/01/helpers/ipfs.ts b/packages/subgraph/src/mappings/01/helpers/ipfs.ts new file mode 100644 index 00000000..26fc43a4 --- /dev/null +++ b/packages/subgraph/src/mappings/01/helpers/ipfs.ts @@ -0,0 +1,99 @@ +import { + BigInt, + Bytes, + ipfs, + json, + log, + JSONValue, +} from '@graphprotocol/graph-ts'; + +import { Agreement } from '../../../types/schema'; +import { InvoiceObject, addQm } from '../utils'; + +function handleAgreementFile(projectArray: Array): Agreement[] { + let agreementArray = new Array(); + + for (let i = 0; i < projectArray.length; i++) { + let obj = projectArray[i].toObject(); + let type = obj.get('type'); + let src = obj.get('src'); + let createdAt = obj.get('createdAt'); + if (!type || !src || createdAt == null) { + return []; + } + let typeValue = type.toString(); + let srcValue = src.toString(); + let createdAtValue = BigInt.fromString(createdAt.toString()); + + let agreement = new Agreement(createdAtValue.toString()); + + agreement.type = typeValue; + agreement.src = srcValue; + agreement.createdAt = createdAtValue; + + log.info( + 'agreement commit: agreement.type {} agreement.src {} agreement.createdAt {} index {}', + [ + agreement.type, + agreement.src, + agreement.createdAt.toString(), + i.toString(), + ], + ); + + agreement.save(); + + agreementArray[i] = agreement; + } + + return agreementArray; +} + +export function handleIpfsDetails( + details: Bytes, + invoiceObject: InvoiceObject, +): InvoiceObject { + invoiceObject.details = details; + let hexHash = changetype(addQm(invoiceObject.details)); + let base58Hash = hexHash.toBase58(); + invoiceObject.ipfsHash = base58Hash.toString(); + let ipfsData = ipfs.cat(base58Hash); + if (ipfsData === null) { + log.info('IPFS data is null for hash {}', [base58Hash]); + return invoiceObject; + } + + log.info('IPFS details from hash {}, data {}', [ + base58Hash, + ipfsData.toString(), + ]); + let data = json.fromBytes(ipfsData).toObject(); + let projectName = data.get('projectName'); + if (projectName != null && !projectName.isNull()) { + invoiceObject.projectName = projectName.toString(); + } + let projectDescription = data.get('projectDescription'); + if (projectDescription != null && !projectDescription.isNull()) { + invoiceObject.projectDescription = projectDescription.toString(); + } + let projectAgreement = data.get('projectAgreement'); + if (projectAgreement != null && !projectAgreement.isNull()) { + let projectArray = projectAgreement.toArray(); + + let agreementArray = handleAgreementFile(projectArray); + + if (agreementArray) { + invoiceObject.projectAgreement = agreementArray; + } + } + let startDate = data.get('startDate'); + if (startDate != null && !startDate.isNull()) { + invoiceObject.startDate = startDate.toBigInt(); + } + let endDate = data.get('endDate'); + if (endDate != null && !endDate.isNull()) { + invoiceObject.endDate = endDate.toBigInt(); + } + + return invoiceObject; +} diff --git a/packages/subgraph/src/mappings/01/helpers/split-escrow.ts b/packages/subgraph/src/mappings/01/helpers/split-escrow.ts index 2ffab945..1a02cda5 100644 --- a/packages/subgraph/src/mappings/01/helpers/split-escrow.ts +++ b/packages/subgraph/src/mappings/01/helpers/split-escrow.ts @@ -1,16 +1,9 @@ -import { - Address, - BigInt, - Bytes, - ByteArray, - ipfs, - json, - log, -} from '@graphprotocol/graph-ts'; +import { Address, log } from '@graphprotocol/graph-ts'; -import { Invoice, Agreement } from '../../../types/schema'; +import { Invoice } from '../../../types/schema'; import { SmartInvoiceSplitEscrow01 } from '../../../types/templates/SmartInvoiceSplitEscrow01/SmartInvoiceSplitEscrow01'; -import { InvoiceObject, addQm } from '../utils'; +import { InvoiceObject } from '../utils'; +import { handleIpfsDetails } from './ipfs'; function fetchSplitEscrowInfo(address: Address): InvoiceObject { let invoiceInstance = SmartInvoiceSplitEscrow01.bind(address); @@ -71,77 +64,7 @@ function fetchSplitEscrowInfo(address: Address): InvoiceObject { } if (!details.reverted) { //needs to be broken out based on invoice type - invoiceObject.details = details.value; - if (details.value.length == 32) { - let hexHash = changetype(addQm(invoiceObject.details)); - let base58Hash = hexHash.toBase58(); - invoiceObject.ipfsHash = base58Hash.toString(); - let ipfsData = ipfs.cat(base58Hash); - if (ipfsData !== null) { - log.info('IPFS details from hash {}, data {}', [ - base58Hash, - ipfsData.toString(), - ]); - let data = json.fromBytes(ipfsData).toObject(); - let projectName = data.get('projectName'); - if (projectName != null && !projectName.isNull()) { - invoiceObject.projectName = projectName.toString(); - } - let projectDescription = data.get('projectDescription'); - if (projectDescription != null && !projectDescription.isNull()) { - invoiceObject.projectDescription = projectDescription.toString(); - } - let projectAgreement = data.get('projectAgreement'); - if (projectAgreement != null && !projectAgreement.isNull()) { - let projectArray = projectAgreement.toArray(); - let agreementArray = new Array(); - - for (let i = 0; i < projectArray.length; i++) { - let obj = projectArray[i].toObject(); - let type = obj.get('type'); - let src = obj.get('src'); - let createdAt = obj.get('createdAt'); - if (type && src && createdAt != null) { - let typeValue = type.toString(); - let srcValue = src.toString(); - let createdAtValue = BigInt.fromString(createdAt.toString()); - - let agreement = new Agreement(createdAtValue.toString()); - - agreement.type = typeValue; - agreement.src = srcValue; - agreement.createdAt = createdAtValue; - - log.info( - 'agreement commit: agreement.type {} agreement.src {} agreement.createdAt {} index {}', - [ - agreement.type, - agreement.src, - agreement.createdAt.toString(), - i.toString(), - ], - ); - - agreement.save(); - - agreementArray[i] = agreement; - } - } - - invoiceObject.projectAgreement = agreementArray; - } - let startDate = data.get('startDate'); - if (startDate != null && !startDate.isNull()) { - invoiceObject.startDate = startDate.toBigInt(); - } - let endDate = data.get('endDate'); - if (endDate != null && !endDate.isNull()) { - invoiceObject.endDate = endDate.toBigInt(); - } - } else { - log.warning('could not get IPFS details from hash {}', [base58Hash]); - } - } + invoiceObject = handleIpfsDetails(details.value, invoiceObject); } if (!dao.reverted) { invoiceObject.dao = dao.value; diff --git a/packages/subgraph/src/mappings/01/helpers/updatable-escrow.ts b/packages/subgraph/src/mappings/01/helpers/updatable-escrow.ts new file mode 100644 index 00000000..abd7b59d --- /dev/null +++ b/packages/subgraph/src/mappings/01/helpers/updatable-escrow.ts @@ -0,0 +1,122 @@ +import { Address, log } from '@graphprotocol/graph-ts'; + +import { Invoice } from '../../../types/schema'; +import { SmartInvoiceEscrow01 } from '../../../types/templates/SmartInvoiceEscrow01/SmartInvoiceEscrow01'; +import { InvoiceObject } from '../utils'; +import { SmartInvoiceUpdatable01 } from '../../../types/templates/SmartInvoiceEscrow01/SmartInvoiceUpdatable01'; +import { handleIpfsDetails } from './ipfs'; + +function fetchEscrowInfo(address: Address): InvoiceObject { + let invoiceInstance = SmartInvoiceEscrow01.bind(address); + let updatableInstance = SmartInvoiceUpdatable01.bind(address); + + let invoiceObject = new InvoiceObject(); + + let client = invoiceInstance.try_client(); + let provider = invoiceInstance.try_provider(); + let providerReceiver = updatableInstance.try_providerReceiver(); + let resolverType = invoiceInstance.try_resolverType(); + let resolver = invoiceInstance.try_resolver(); + let resolutionRate = invoiceInstance.try_resolutionRate(); + let token = invoiceInstance.try_token(); + let locked = invoiceInstance.try_locked(); + let milestone = invoiceInstance.try_milestone(); + let total = invoiceInstance.try_total(); + let released = invoiceInstance.try_released(); + let terminationTime = invoiceInstance.try_terminationTime(); + let details = invoiceInstance.try_details(); + let disputeId = invoiceInstance.try_disputeId(); + + if (!client.reverted) { + invoiceObject.client = client.value; + } + if (!provider.reverted) { + invoiceObject.provider = provider.value; + } + if (!providerReceiver.reverted) { + invoiceObject.providerReceiver = providerReceiver.value; + } + if (!resolverType.reverted) { + invoiceObject.resolverType = resolverType.value; + } + if (!resolver.reverted) { + invoiceObject.resolver = resolver.value; + } + if (!resolutionRate.reverted) { + invoiceObject.resolutionRate = resolutionRate.value; + } + if (!token.reverted) { + invoiceObject.token = token.value; + } + if (!locked.reverted) { + invoiceObject.isLocked = locked.value; + } + if (!milestone.reverted) { + invoiceObject.currentMilestone = milestone.value; + } + if (!total.reverted) { + invoiceObject.total = total.value; + } + if (!released.reverted) { + invoiceObject.released = released.value; + } + if (!terminationTime.reverted) { + invoiceObject.terminationTime = terminationTime.value; + } + if (!disputeId.reverted) { + invoiceObject.disputeId = disputeId.value; + } + if (!details.reverted) { + //needs to be broken out based on invoice type + invoiceObject = handleIpfsDetails(details.value, invoiceObject); + } + + return invoiceObject; +} + +export function updateUpdatableInfo( + address: Address, + invoice: Invoice, +): Invoice { + let invoiceObject = fetchEscrowInfo(address); + + log.info('Got details for invoice', [address.toHexString()]); + + invoice.token = invoiceObject.token; + invoice.client = invoiceObject.client; + invoice.provider = invoiceObject.provider; + if (invoiceObject.resolverType == 0) { + invoice.resolverType = 'individual'; + } else if (invoiceObject.resolverType == 1) { + invoice.resolverType = 'arbitrator'; + } + invoice.resolver = invoiceObject.resolver; + invoice.resolutionRate = invoiceObject.resolutionRate; + invoice.isLocked = invoiceObject.isLocked; + invoice.currentMilestone = invoiceObject.currentMilestone; + invoice.total = invoiceObject.total; + invoice.released = invoiceObject.released; + invoice.terminationTime = invoiceObject.terminationTime; + invoice.details = invoiceObject.details; + invoice.ipfsHash = invoiceObject.ipfsHash; + invoice.disputeId = invoiceObject.disputeId; + invoice.projectName = invoiceObject.projectName; + invoice.projectDescription = invoiceObject.projectDescription; + invoice.startDate = invoiceObject.startDate; + invoice.endDate = invoiceObject.endDate; + invoice.providerReceiver = invoiceObject.providerReceiver; + + invoice.projectAgreement.length = 0; + let projectAgreement = new Array(); + let sourceAgreements = invoiceObject.projectAgreement; + + for (let i = 0; i < sourceAgreements.length; i++) { + projectAgreement[i] = sourceAgreements[i].id; + } + + invoice.projectAgreement = projectAgreement; + + log.info('fox tango {}', [invoice.projectName.toString()]); + + return invoice as Invoice; +} diff --git a/packages/subgraph/src/mappings/01/utils.ts b/packages/subgraph/src/mappings/01/utils.ts index 07972fc4..fd208cb7 100644 --- a/packages/subgraph/src/mappings/01/utils.ts +++ b/packages/subgraph/src/mappings/01/utils.ts @@ -1,18 +1,11 @@ -import { - Address, - BigInt, - Bytes, - ByteArray, - ipfs, - json, - log, -} from '@graphprotocol/graph-ts'; +import { Address, BigInt, Bytes, ByteArray } from '@graphprotocol/graph-ts'; import { Agreement, Invoice } from '../../types/schema'; import { updateEscrowInfo } from './helpers/escrow'; import { updateInstantInfo } from './helpers/instant'; import { updateSplitEscrowInfo } from './helpers/split-escrow'; +import { updateUpdatableInfo } from './helpers/updatable-escrow'; let zeroAddress = changetype
( Address.fromHexString('0x0000000000000000000000000000000000000000'), @@ -49,10 +42,12 @@ export class InvoiceObject { fulfilled: boolean; dao: Address; daoFee: BigInt; + providerReceiver: Address; constructor() { this.client = zeroAddress; this.provider = zeroAddress; + this.providerReceiver = zeroAddress; this.resolverType = 0; this.resolver = zeroAddress; this.resolutionRate = BigInt.fromI32(0); @@ -100,6 +95,8 @@ export function updateInvoice(address: Address, invoice: Invoice): Invoice { invoice = updateEscrowInfo(address, invoice); } else if (type == 'split-escrow') { invoice = updateSplitEscrowInfo(address, invoice); + } else if (type == 'updatable') { + invoice = updateUpdatableInfo(address, invoice); } else { invoice = updateInstantInfo(address, invoice); } diff --git a/packages/subgraph/src/schema.graphql b/packages/subgraph/src/schema.graphql index 07307166..f219e1b4 100644 --- a/packages/subgraph/src/schema.graphql +++ b/packages/subgraph/src/schema.graphql @@ -48,6 +48,8 @@ type Invoice @entity { # split-escrow type specific dao: Bytes daoFee: BigInt + # updatable fields + providerReceiver: Bytes } enum ADR @entity { @@ -71,7 +73,6 @@ type Agreement @entity { createdAt: BigInt! } - type Release @entity { id: ID! txHash: Bytes! @@ -141,5 +142,5 @@ type MilestonesAdded @entity { type Tip @entity { id: ID! sender: Bytes! - amount: BigInt! + amount: BigInt! } diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml index f31734b8..2751bcbe 100644 --- a/packages/subgraph/subgraph.template.yaml +++ b/packages/subgraph/subgraph.template.yaml @@ -35,6 +35,8 @@ dataSources: file: ./src/abis/{{factoryName}}/SmartInvoiceInstant{{factoryName}}.json - name: SmartInvoiceSplitEscrow{{factoryName}} file: ./src/abis/{{factoryName}}/SmartInvoiceSplitEscrow{{factoryName}}.json + - name: SmartInvoiceUpdatable{{factoryName}} + file: ./src/abis/{{factoryName}}/SmartInvoiceSplitEscrow{{factoryName}}.json {{/v01}} - name: SmartInvoiceFactory{{factoryName}} file: ./src/abis/{{factoryName}}/SmartInvoiceFactory{{factoryName}}.json @@ -210,6 +212,53 @@ templates: - event: MilestonesAdded(indexed address,indexed address,uint256[]) handler: handleMilestonesAdded file: ./src/mappings/{{factoryName}}/invoice.ts + - kind: ethereum/contract + name: SmartInvoiceUpdatable{{factoryName}} + # prettier-ignore + network: {{network}} + source: + abi: SmartInvoiceUpdatable{{factoryName}} + mapping: + kind: ethereum/events + apiVersion: 0.0.6 + language: wasm/assemblyscript + entities: + - Invoice + - Release + - Deposit + - Resolution + - Token + abis: + - name: ERC20 + file: ./src/abis/ERC20.json + - name: SmartInvoiceUpdatable{{factoryName}} + file: ./src/abis/{{factoryName}}/SmartInvoiceUpdatable{{factoryName}}.json + - name: SmartInvoiceFactory{{factoryName}} + file: ./src/abis/{{factoryName}}/SmartInvoiceFactory{{factoryName}}.json + eventHandlers: + - event: Release(uint256,uint256) + handler: handleRelease + - event: Withdraw(uint256) + handler: handleWithdraw + - event: Lock(indexed address,bytes32) + handler: handleLock + - event: Rule(indexed address,uint256,uint256,uint256) + handler: handleRule + - event: Resolve(indexed address,uint256,uint256,uint256,bytes32) + handler: handleResolve + - event: Deposit(indexed address,uint256) + handler: handleDeposit + - event: Verified(indexed address,indexed address) + handler: handleVerified + - event: MilestonesAdded(indexed address,indexed address,uint256[]) + handler: handleMilestonesAdded + # - event: UpdateClient(indexed address) + # handler: handleUpdateClient + # - event: UpdateProvider(indexed address) + # handler: handleUpdateProvider + # - event: UpdateProviderReceiver(indexed address) + # handler: handleUpdateProviderReceiver + file: ./src/mappings/{{factoryName}}/invoice.ts {{/v01}} {{/factories}} - kind: ethereum/contract diff --git a/packages/subgraph/subgraph.yaml b/packages/subgraph/subgraph.yaml index a4a5e41f..7948a960 100644 --- a/packages/subgraph/subgraph.yaml +++ b/packages/subgraph/subgraph.yaml @@ -2,18 +2,15 @@ specVersion: 0.0.4 description: Smart Invoice schema: file: ./src/schema.graphql -features: - [ipfsOnEthereumContracts] +features: [ipfsOnEthereumContracts] dataSources: - kind: ethereum/contract name: SmartInvoiceFactory00 - # prettier-ignore - network: goerli + network: mainnet source: address: '0x566ac8344a7cbBC4879e5692F32A9ebdED002e7f' abi: SmartInvoiceFactory00 - # prettier-ignore - startBlock: 9556965 + startBlock: 15546992 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -30,17 +27,15 @@ dataSources: eventHandlers: - event: LogNewInvoice(indexed uint256,address,uint256[]) handler: handleLogNewInvoice - + file: ./src/mappings/00/factory.ts - kind: ethereum/contract name: SmartInvoiceFactory01 - # prettier-ignore - network: goerli + network: mainnet source: address: '0x546adED0B0179d550e87cf909939a1207Fd26fB7' abi: SmartInvoiceFactory01 - # prettier-ignore - startBlock: 9556965 + startBlock: 16991083 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -61,13 +56,12 @@ dataSources: eventHandlers: - event: LogNewInvoice(indexed uint256,indexed address,uint256[],bytes32,uint256) handler: handleLogNewInvoice - + file: ./src/mappings/01/factory.ts templates: - kind: ethereum/contract name: SmartInvoice00 - # prettier-ignore - network: goerli + network: mainnet source: abi: SmartInvoice00 mapping: @@ -107,8 +101,7 @@ templates: file: ./src/mappings/00/invoice.ts - kind: ethereum/contract name: SmartInvoiceEscrow01 - # prettier-ignore - network: goerli + network: mainnet source: abi: SmartInvoiceEscrow01 mapping: @@ -126,6 +119,8 @@ templates: file: ./src/abis/ERC20.json - name: SmartInvoiceEscrow01 file: ./src/abis/01/SmartInvoiceEscrow01.json + - name: SmartInvoiceUpdatable01 + file: ./src/abis/01/SmartInvoiceUpdatable01.json - name: SmartInvoiceFactory01 file: ./src/abis/01/SmartInvoiceFactory01.json eventHandlers: @@ -148,8 +143,7 @@ templates: file: ./src/mappings/01/invoice.ts - kind: ethereum/contract name: SmartInvoiceInstant01 - # prettier-ignore - network: goerli + network: mainnet source: abi: SmartInvoiceInstant01 mapping: @@ -180,8 +174,7 @@ templates: file: ./src/mappings/01/invoice.ts - kind: ethereum/contract name: SmartInvoiceSplitEscrow01 - # prettier-ignore - network: goerli + network: mainnet source: abi: SmartInvoiceSplitEscrow01 mapping: @@ -219,10 +212,55 @@ templates: - event: MilestonesAdded(indexed address,indexed address,uint256[]) handler: handleMilestonesAdded file: ./src/mappings/01/invoice.ts + - kind: ethereum/contract + name: SmartInvoiceUpdatable01 + network: mainnet + source: + abi: SmartInvoiceUpdatable01 + mapping: + kind: ethereum/events + apiVersion: 0.0.6 + language: wasm/assemblyscript + entities: + - Invoice + - Release + - Deposit + - Resolution + - Token + abis: + - name: ERC20 + file: ./src/abis/ERC20.json + - name: SmartInvoiceUpdatable01 + file: ./src/abis/01/SmartInvoiceUpdatable01.json + - name: SmartInvoiceFactory01 + file: ./src/abis/01/SmartInvoiceFactory01.json + eventHandlers: + - event: Release(uint256,uint256) + handler: handleRelease + - event: Withdraw(uint256) + handler: handleWithdraw + - event: Lock(indexed address,bytes32) + handler: handleLock + - event: Rule(indexed address,uint256,uint256,uint256) + handler: handleRule + - event: Resolve(indexed address,uint256,uint256,uint256,bytes32) + handler: handleResolve + - event: Deposit(indexed address,uint256) + handler: handleDeposit + - event: Verified(indexed address,indexed address) + handler: handleVerified + - event: MilestonesAdded(indexed address,indexed address,uint256[]) + handler: handleMilestonesAdded + # - event: UpdateClient(indexed address) + # handler: handleUpdateClient + # - event: UpdateProvider(indexed address) + # handler: handleUpdateProvider + # - event: UpdateProviderReceiver(indexed address) + # handler: handleUpdateProviderReceiver + file: ./src/mappings/01/invoice.ts - kind: ethereum/contract name: ERC20 - # prettier-ignore - network: goerli + network: mainnet source: abi: ERC20 mapping: @@ -250,4 +288,4 @@ templates: eventHandlers: - event: Transfer(indexed address,indexed address,uint256) handler: handleTransfer - file: ./src/mappings/token.ts \ No newline at end of file + file: ./src/mappings/token.ts From 641565fc648269914f7626803762d648ff837a97 Mon Sep 17 00:00:00 2001 From: scottrepreneur Date: Sat, 18 Nov 2023 09:27:22 -0600 Subject: [PATCH 5/8] use public variables intead of get lookup --- .../contracts/SafeSplitsDaoEscrowZap.sol | 4 +- .../contracts/SafeSplitsEscrowZap.sol | 48 +++---------------- packages/contracts/deployments/gnosis.json | 18 ++++++- packages/contracts/package.json | 2 +- packages/contracts/scripts/check-zap.js | 25 ++++++++-- 5 files changed, 47 insertions(+), 50 deletions(-) diff --git a/packages/contracts/contracts/SafeSplitsDaoEscrowZap.sol b/packages/contracts/contracts/SafeSplitsDaoEscrowZap.sol index 9c6d321b..fdd86808 100644 --- a/packages/contracts/contracts/SafeSplitsDaoEscrowZap.sol +++ b/packages/contracts/contracts/SafeSplitsDaoEscrowZap.sol @@ -11,12 +11,12 @@ import "./interfaces/ISpoilsManager.sol"; contract SafeSplitsDaoEscrowZap is SafeSplitsEscrowZap { /// @notice The DAO controller address - address dao; + address public dao; error DaoSplitCreationFailed(); /// @notice The DAO's SpoilsManager address - ISpoilsManager spoilsManager; + ISpoilsManager public spoilsManager; event SafeSplitsDaoEscrowCreated( address safe, diff --git a/packages/contracts/contracts/SafeSplitsEscrowZap.sol b/packages/contracts/contracts/SafeSplitsEscrowZap.sol index d316836b..aaa17cef 100644 --- a/packages/contracts/contracts/SafeSplitsEscrowZap.sol +++ b/packages/contracts/contracts/SafeSplitsEscrowZap.sol @@ -15,25 +15,25 @@ import "./interfaces/IWRAPPED.sol"; contract SafeSplitsEscrowZap is AccessControl, Initializable { /// @notice The SafeL2 singleton address - address safeSingleton; + address public safeSingleton; /// @notice The fallback handler address - address fallbackHandler; + address public fallbackHandler; /// @notice The Safe proxy factory address - ISafeProxyFactory safeFactory; + ISafeProxyFactory public safeFactory; /// @notice The SplitMain address - ISplitMain splitMain; + ISplitMain public splitMain; /// @notice The SmartInvoiceFactory address - ISmartInvoiceFactory escrowFactory; + ISmartInvoiceFactory public escrowFactory; /// @notice The wrapped native token (WETH) address - IWRAPPED wrappedNativeToken; + IWRAPPED public wrappedNativeToken; /// @notice The distributor fee provided for processing 0xSplits - uint32 distributorFee = 0; + uint32 public distributorFee = 0; bytes32 public constant ADMIN = keccak256("ADMIN"); @@ -316,40 +316,6 @@ contract SafeSplitsEscrowZap is AccessControl, Initializable { ); } - // VIEW - - /** - * @dev Views the addresses of the contracts used in the zap - * @return address Safe singleton address - * @return address Safe fallback handler address - * @return address SplitMain address - * @return address EscrowFactory address - * @return address SpoilsManager address - * @return address WrappedNativeToken address - */ - function getAddresses() - public - view - returns (address, address, address, address, address, address) - { - return ( - safeSingleton, - fallbackHandler, - address(safeFactory), - address(splitMain), - address(escrowFactory), - address(wrappedNativeToken) - ); - } - - /** - * @dev Views the distributor fee used in the zap - * @return uint32 The distributor fee provided for processing splits - */ - function getDistributorFee() public view returns (uint32) { - return distributorFee; - } - function _updateAddresses(bytes calldata _data) internal { ( address _safeSingleton, diff --git a/packages/contracts/deployments/gnosis.json b/packages/contracts/deployments/gnosis.json index bbfaff84..27836b31 100644 --- a/packages/contracts/deployments/gnosis.json +++ b/packages/contracts/deployments/gnosis.json @@ -6,6 +6,22 @@ "implementations": { "escrow": ["0x695252527A3bCbB006aAb3D0b7490e6d6d47faDE"], "instant": ["0xaA4C3b427A441e436f624AcC9cc72E79f66B6066"], - "split-escrow": ["0x84c4EC5F1931b552405cB238E8FE30ef8Ac48134"] + "split-escrow": ["0x84c4EC5F1931b552405cB238E8FE30ef8Ac48134"], + "updatable": ["0xB3F3a1F1085aDF41a29b80839789CEd0b2089776"] + }, + "spoilsManager": { + "factory": "0xc3a56196B7864fCe4b27480D62Dc9263A2168190", + "implementation": ["0xA817ba0646001EcF56Cc271B7fE7e10269AE54dD"] + }, + "zap": { + "dao": "0xa4161dB839F84E27122398aE6337AD47765E6cD5", + "safeSingleton": "0x3E5c63644E683549055b9Be8653de26E0B4CD36E", + "fallbackHandler": "0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4", + "safeFactory": "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", + "splitMain": "0x2ed6c4B5dA6378c7897AC67Ba9e43102Feb694EE", + "spoilsManager": "0x7C0Ca40d9806c71B5234eDD0f75E5baebE6eCE00", + "factory": "0xbdB550A76cBa692F1a0B328ae1B3c932FEb7301F", + "implementations": ["0xe33A71c7Cda9EDc22B40ff45c9F58F10d348B5aD"], + "instances": ["0xED148E49149Ed48331f4f34974568418dfb2964F"] } } diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 00d7b648..b0af9673 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -33,7 +33,7 @@ "flatten-spoils": "hardhat flatten contracts/SpoilsManager.sol | awk '/SPDX-License-Identifier/&&c++>0 {next} 1' | awk '/pragma experimental ABIEncoderV2;/&&c++>0 {next} 1' > flat/SpoilsManager.sol", "flatten-zap": "hardhat flatten contracts/SafeSplitsEscrowZap.sol | awk '/SPDX-License-Identifier/&&c++>0 {next} 1' | awk '/pragma experimental ABIEncoderV2;/&&c++>0 {next} 1' > flat/SafeSplitsEscrowZap.sol", "flatten-dao-zap": "hardhat flatten contracts/SafeSplitsDaoEscrowZap.sol | awk '/SPDX-License-Identifier/&&c++>0 {next} 1' | awk '/pragma experimental ABIEncoderV2;/&&c++>0 {next} 1' > flat/SafeSplitsDaoEscrowZap.sol", - "flatten-all": "yarn flatten-factory && yarn flatten-instant && yarn flatten-escrow && yarn flatten-updatable && yarn flatten-spoils && yarn flatten-spoils-factory && yarn flatten-zap && yarn flatten-dao-zap && yarn flatten-zap-factory" + "flatten-all": "yarn flatten-factory && yarn flatten-instant && yarn flatten-escrow && yarn flatten-updatable && yarn flatten-spoils && yarn flatten-zap && yarn flatten-dao-zap" }, "dependencies": { "@ethersproject/address": "^5.1.0", diff --git a/packages/contracts/scripts/check-zap.js b/packages/contracts/scripts/check-zap.js index e52c6311..636ef8e3 100644 --- a/packages/contracts/scripts/check-zap.js +++ b/packages/contracts/scripts/check-zap.js @@ -6,8 +6,6 @@ async function main() { const [deployer] = await ethers.getSigners(); const { chainId } = await deployer.provider.getNetwork(); - // todo handle other networks - if (chainId !== 5 && chainId !== 31337) return; const zapData = getZapData(chainId); const safeSplitsEscrowZapAddress = zapData.instances && zapData.instances[0]; @@ -17,12 +15,29 @@ async function main() { } const safeSplitsEscrowZap = await ethers.getContractAt( - "SafeSplitsEscrowZap", + "SafeSplitsDaoEscrowZap", safeSplitsEscrowZapAddress, ); - const addresses = await safeSplitsEscrowZap.getAddresses(); - console.log(addresses); + const addressList = [ + "safeSingleton", + "fallbackHandler", + "safeFactory", + "splitMain", + "escrowFactory", + "wrappedNativeToken", + "spoilsManager", + "dao", + ]; + + const addressFetch = addressList.map(async type => + safeSplitsEscrowZap[type](), + ); + + const addresses = await Promise.all(addressFetch); + console.log( + addresses.map((address, index) => `${addressList[index]}: ${address}`), + ); } main() From 82998daf1a94124129f79b5c397afa28ed040031 Mon Sep 17 00:00:00 2001 From: scottrepreneur Date: Thu, 23 Nov 2023 07:55:04 -0600 Subject: [PATCH 6/8] flex safe and split creation --- .../contracts/SafeSplitsDaoEscrowZap.sol | 111 ++++-------- .../contracts/SafeSplitsEscrowZap.sol | 167 ++++++------------ packages/contracts/deployments/gnosis.json | 9 +- packages/contracts/hardhat.config.js | 2 +- .../contracts/test/SafeSplitsDaoEscrowZap.js | 26 +-- .../contracts/test/SafeSplitsEscrowZap.js | 21 ++- packages/contracts/test/utils.js | 2 + 7 files changed, 125 insertions(+), 213 deletions(-) diff --git a/packages/contracts/contracts/SafeSplitsDaoEscrowZap.sol b/packages/contracts/contracts/SafeSplitsDaoEscrowZap.sol index fdd86808..7a76b167 100644 --- a/packages/contracts/contracts/SafeSplitsDaoEscrowZap.sol +++ b/packages/contracts/contracts/SafeSplitsDaoEscrowZap.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.4; -import "hardhat/console.sol"; import "@openzeppelin/contracts/proxy/Clones.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; @@ -18,12 +17,7 @@ contract SafeSplitsDaoEscrowZap is SafeSplitsEscrowZap { /// @notice The DAO's SpoilsManager address ISpoilsManager public spoilsManager; - event SafeSplitsDaoEscrowCreated( - address safe, - address projectTeamSplit, - address daoSplit, - address escrow - ); + event SafeSplitsDaoEscrowCreated(address safe, address projectTeamSplit, address daoSplit, address escrow); struct DaoZapData { ZapData zapData; @@ -43,19 +37,21 @@ contract SafeSplitsDaoEscrowZap is SafeSplitsEscrowZap { bytes calldata _splitsData, DaoZapData memory _daoZapData ) internal returns (DaoZapData memory) { - _daoZapData.zapData.projectTeamSplit = splitMain.createSplit( - _owners, - _percentAllocations, - distributorFee, - _daoZapData.zapData.safe - ); - if (_daoZapData.zapData.projectTeamSplit == address(0)) { - revert ProjectTeamSplitNotCreated(); + (bool projectSplit, bool daoSplit) = abi.decode(_splitsData, (bool, bool)); + if (projectSplit) { + _daoZapData.zapData.projectTeamSplit = + splitMain.createSplit(_owners, _percentAllocations, distributorFee, _daoZapData.zapData.safe); } - bool _isDaoSplit = abi.decode(_splitsData, (bool)); + if (_daoZapData.zapData.projectTeamSplit == address(0)) { + if (_daoZapData.zapData.safe != address(0)) { + _daoZapData.zapData.projectTeamSplit = _daoZapData.zapData.safe; + } else { + revert ProjectTeamSplitNotCreated(); + } + } - if (_isDaoSplit) { + if (daoSplit) { // prepare arrays address[] memory daoSplitRecipients = new address[](2); uint32[] memory daoSplitPercentAllocations = new uint32[](2); @@ -65,14 +61,10 @@ contract SafeSplitsDaoEscrowZap is SafeSplitsEscrowZap { // dao split amounts uint32 daoSplitAmount = spoilsManager.getSpoils(); - uint32 projectSplitAmount = (100 * - spoilsManager.SPLIT_PERCENTAGE_SCALE()) - (daoSplitAmount); + uint32 projectSplitAmount = (100 * spoilsManager.SPLIT_PERCENTAGE_SCALE()) - (daoSplitAmount); // sort the addresses into the correct order - if ( - uint160(daoReceiver) < - uint160(_daoZapData.zapData.projectTeamSplit) - ) { + if (uint160(daoReceiver) < uint160(_daoZapData.zapData.projectTeamSplit)) { daoSplitRecipients[0] = daoReceiver; daoSplitRecipients[1] = _daoZapData.zapData.projectTeamSplit; daoSplitPercentAllocations[0] = daoSplitAmount; @@ -85,12 +77,8 @@ contract SafeSplitsDaoEscrowZap is SafeSplitsEscrowZap { } // (recipients array, percent allocations array, no distributor fee, safe address) - _daoZapData.daoSplit = splitMain.createSplit( - daoSplitRecipients, - daoSplitPercentAllocations, - distributorFee, - dao - ); + _daoZapData.daoSplit = + splitMain.createSplit(daoSplitRecipients, daoSplitPercentAllocations, distributorFee, dao); if (_daoZapData.daoSplit == address(0)) { revert DaoSplitCreationFailed(); } @@ -99,9 +87,7 @@ contract SafeSplitsDaoEscrowZap is SafeSplitsEscrowZap { return _daoZapData; } - function _handleEscrowParams( - DaoZapData memory _daoZapData - ) internal view returns (address[] memory) { + function _handleEscrowParams(DaoZapData memory _daoZapData) internal view returns (address[] memory) { address[] memory escrowParams = new address[](2); escrowParams[0] = _daoZapData.zapData.safe; escrowParams[1] = _daoZapData.zapData.projectTeamSplit; @@ -119,45 +105,28 @@ contract SafeSplitsDaoEscrowZap is SafeSplitsEscrowZap { uint32[] memory _percentAllocations, uint256[] memory _milestoneAmounts, bytes calldata _safeData, + address _safeAddress, bytes calldata _splitsData, bytes calldata _escrowData - ) internal { + ) internal override { + // pass safeAddress by default DaoZapData memory daoZapData = DaoZapData({ - zapData: ZapData({ - safe: address(0), - projectTeamSplit: address(0), - escrow: address(0) - }), + zapData: ZapData({safe: _safeAddress, projectTeamSplit: address(0), escrow: address(0)}), daoSplit: address(0) }); - daoZapData.zapData = _deploySafe( - _owners, - _safeData, - daoZapData.zapData - ); + if (daoZapData.zapData.safe == address(0)) { + daoZapData.zapData = _deploySafe(_owners, _safeData, daoZapData.zapData); + } - daoZapData = _createSplit( - _owners, - _percentAllocations, - _splitsData, - daoZapData - ); + daoZapData = _createSplit(_owners, _percentAllocations, _splitsData, daoZapData); address[] memory escrowParams = _handleEscrowParams(daoZapData); - daoZapData.zapData = _deployEscrow( - _milestoneAmounts, - _escrowData, - escrowParams, - daoZapData.zapData - ); + daoZapData.zapData = _deployEscrow(_milestoneAmounts, _escrowData, escrowParams, daoZapData.zapData); emit SafeSplitsDaoEscrowCreated( - daoZapData.zapData.safe, - daoZapData.zapData.projectTeamSplit, - daoZapData.daoSplit, - daoZapData.zapData.escrow + daoZapData.zapData.safe, daoZapData.zapData.projectTeamSplit, daoZapData.daoSplit, daoZapData.zapData.escrow ); } @@ -174,19 +143,15 @@ contract SafeSplitsDaoEscrowZap is SafeSplitsEscrowZap { uint32[] memory _percentAllocations, uint256[] memory _milestoneAmounts, bytes calldata _safeData, + address _safeAddress, bytes calldata _splitsData, bytes calldata _escrowData - ) public { + ) public override { if (_percentAllocations.length != _owners.length) { revert InvalidAllocationsOwnersData(); } _createSafeSplitEscrow( - _owners, - _percentAllocations, - _milestoneAmounts, - _safeData, - _splitsData, - _escrowData + _owners, _percentAllocations, _milestoneAmounts, _safeData, _safeAddress, _splitsData, _escrowData ); } @@ -200,19 +165,7 @@ contract SafeSplitsDaoEscrowZap is SafeSplitsEscrowZap { address _escrowFactory, address _wrappedNativeToken, address _dao - ) = abi.decode( - _data, - ( - address, - address, - address, - address, - address, - address, - address, - address - ) - ); + ) = abi.decode(_data, (address, address, address, address, address, address, address, address)); safeSingleton = _safeSingleton; fallbackHandler = _fallbackHandler; diff --git a/packages/contracts/contracts/SafeSplitsEscrowZap.sol b/packages/contracts/contracts/SafeSplitsEscrowZap.sol index aaa17cef..71348e9e 100644 --- a/packages/contracts/contracts/SafeSplitsEscrowZap.sol +++ b/packages/contracts/contracts/SafeSplitsEscrowZap.sol @@ -43,17 +43,8 @@ contract SafeSplitsEscrowZap is AccessControl, Initializable { error EscrowNotCreated(); error NotAuthorized(); - event SafeSplitsEscrowCreated( - address safe, - address projectTeamSplit, - address escrow - ); - event UpdatedAddresses( - address safeSingleton, - address safeFactory, - address splitMain, - address escrowFactory - ); + event SafeSplitsEscrowCreated(address safe, address projectTeamSplit, address escrow); + event UpdatedAddresses(address safeSingleton, address safeFactory, address splitMain, address escrowFactory); event UpdatedDistributorFee(uint32 distributorFee); struct ZapData { @@ -61,6 +52,7 @@ contract SafeSplitsEscrowZap is AccessControl, Initializable { address projectTeamSplit; address escrow; } + struct EscrowData { address client; uint8 arbitration; @@ -89,10 +81,7 @@ contract SafeSplitsEscrowZap is AccessControl, Initializable { address _splitMain, address _escrowFactory, address _wrappedNativeToken - ) = abi.decode( - _data, - (address, address, address, address, address, address) - ); + ) = abi.decode(_data, (address, address, address, address, address, address)); safeSingleton = _safeSingleton; fallbackHandler = _fallbackHandler; @@ -108,22 +97,14 @@ contract SafeSplitsEscrowZap is AccessControl, Initializable { * @param _safeData The number of required confirmations for a Safe transaction * @param _zapData Resulting data struct */ - function _deploySafe( - address[] memory _owners, - bytes calldata _safeData, - ZapData memory _zapData - ) internal returns (ZapData memory) { - (uint256 _threshold, uint256 _saltNonce) = abi.decode( - _safeData, - (uint256, uint256) - ); + function _deploySafe(address[] memory _owners, bytes calldata _safeData, ZapData memory _zapData) + internal + returns (ZapData memory) + { + (uint256 _threshold, uint256 _saltNonce) = abi.decode(_safeData, (uint256, uint256)); bytes memory safeInitializer = abi.encodeWithSelector( - bytes4( - keccak256( - "setup(address[],uint256,address,bytes,address,address,uint256,address)" - ) - ), + bytes4(keccak256("setup(address[],uint256,address,bytes,address,address,uint256,address)")), _owners, _threshold, address(0), // to @@ -135,11 +116,7 @@ contract SafeSplitsEscrowZap is AccessControl, Initializable { ); // (implementation address, initializer data, salt nonce) - _zapData.safe = safeFactory.createProxyWithNonce( - safeSingleton, - safeInitializer, - _saltNonce - ); + _zapData.safe = safeFactory.createProxyWithNonce(safeSingleton, safeInitializer, _saltNonce); if (_zapData.safe == address(0)) { revert SafeNotCreated(); } @@ -156,15 +133,16 @@ contract SafeSplitsEscrowZap is AccessControl, Initializable { function _createSplit( address[] memory _owners, uint32[] memory _percentAllocations, + bytes calldata _splitData, ZapData memory _zapData ) internal returns (ZapData memory) { + bool projectSplit = abi.decode(_splitData, (bool)); + if (!projectSplit) { + return _zapData; + } + // (recipients array, percent allocations array, no distributor fee, safe address) - _zapData.projectTeamSplit = splitMain.createSplit( - _owners, - _percentAllocations, - distributorFee, - _zapData.safe - ); + _zapData.projectTeamSplit = splitMain.createSplit(_owners, _percentAllocations, distributorFee, _zapData.safe); if (_zapData.projectTeamSplit == address(0)) { revert ProjectTeamSplitNotCreated(); @@ -173,9 +151,7 @@ contract SafeSplitsEscrowZap is AccessControl, Initializable { return _zapData; } - function _handleEscrowData( - bytes calldata _escrowData - ) internal pure returns (EscrowData memory) { + function _handleEscrowData(bytes calldata _escrowData) internal pure returns (EscrowData memory) { ( address client, uint32 arbitration, @@ -184,10 +160,7 @@ contract SafeSplitsEscrowZap is AccessControl, Initializable { uint256 terminationTime, uint256 _saltNonce, bytes32 details - ) = abi.decode( - _escrowData, - (address, uint32, address, address, uint256, uint256, bytes32) - ); + ) = abi.decode(_escrowData, (address, uint32, address, address, uint256, uint256, bytes32)); EscrowData memory escrowData = EscrowData({ client: client, @@ -233,8 +206,8 @@ contract SafeSplitsEscrowZap is AccessControl, Initializable { // deploy SplitEscrow _zapData.escrow = escrowFactory.createDeterministic( - _escrowParams[0], - _milestoneAmounts, + _escrowParams[0], // provider + _milestoneAmounts, // milestoneAmounts escrowDetails, bytes32("updatable"), escrowData.saltNonce @@ -246,13 +219,16 @@ contract SafeSplitsEscrowZap is AccessControl, Initializable { return _zapData; } - function _handleEscrowParams( - ZapData memory _zapData - ) internal pure returns (address[] memory) { + function _handleEscrowParams(ZapData memory _zapData) internal pure returns (address[] memory) { address[] memory escrowParams = new address[](2); escrowParams[0] = _zapData.safe; - escrowParams[1] = _zapData.projectTeamSplit; + if (_zapData.projectTeamSplit != address(0)) { + escrowParams[1] = _zapData.projectTeamSplit; + return escrowParams; + } + + escrowParams[1] = _zapData.safe; return escrowParams; } @@ -261,68 +237,56 @@ contract SafeSplitsEscrowZap is AccessControl, Initializable { uint32[] memory _percentAllocations, uint256[] memory _milestoneAmounts, bytes calldata _safeData, + address _safeAddress, + bytes calldata _splitData, bytes calldata _escrowData ) internal virtual { - ZapData memory zapData = ZapData({ - safe: address(0), - projectTeamSplit: address(0), - escrow: address(0) - }); + ZapData memory zapData = ZapData({safe: _safeAddress, projectTeamSplit: address(0), escrow: address(0)}); - zapData = _deploySafe(_owners, _safeData, zapData); + if (zapData.safe == address(0)) { + zapData = _deploySafe(_owners, _safeData, zapData); + } - zapData = _createSplit(_owners, _percentAllocations, zapData); + zapData = _createSplit(_owners, _percentAllocations, _splitData, zapData); address[] memory escrowParams = _handleEscrowParams(zapData); - zapData = _deployEscrow( - _milestoneAmounts, - _escrowData, - escrowParams, - zapData - ); + zapData = _deployEscrow(_milestoneAmounts, _escrowData, escrowParams, zapData); - emit SafeSplitsEscrowCreated( - zapData.safe, - zapData.projectTeamSplit, - zapData.escrow - ); + emit SafeSplitsEscrowCreated(zapData.safe, zapData.projectTeamSplit, zapData.escrow); } /** - * @dev Deploys a new Safe, Raid Party Split and Escrow with the provided details - * @param _owners The safe owners and raid party split participants - * @param _percentAllocations The percent allocations for the raid party split + * @dev Deploys a new Safe, Project Team Split and Escrow with the provided details + * @param _owners The safe owners and project team participants + * @param _percentAllocations The percent allocations for the project team split * @param _milestoneAmounts The initial milestone amounts for the escrow - * @param _safeData The number of required confirmations for a Safe transaction - * @param _escrowData The nonce for the salt used in the escrow deployment (recycled from safe deployment) + * @param _safeData The encoded data for deploying a Safe + * @param _safeAddress The address of an existing Safe + * @param _splitData The encoded data for deploying a Split + * @param _escrowData The encoded data for escrow deployment (recycled from safe deployment) */ function createSafeSplitEscrow( address[] memory _owners, uint32[] memory _percentAllocations, uint256[] memory _milestoneAmounts, bytes calldata _safeData, + address _safeAddress, + bytes calldata _splitData, bytes calldata _escrowData - ) public { + ) public virtual { if (_percentAllocations.length != _owners.length) { revert InvalidAllocationsOwnersData(); } + _createSafeSplitEscrow( - _owners, - _percentAllocations, - _milestoneAmounts, - _safeData, - _escrowData + _owners, _percentAllocations, _milestoneAmounts, _safeData, _safeAddress, _splitData, _escrowData ); } function _updateAddresses(bytes calldata _data) internal { - ( - address _safeSingleton, - address _safeFactory, - address _splitMain, - address _escrowFactory - ) = abi.decode(_data, (address, address, address, address)); + (address _safeSingleton, address _safeFactory, address _splitMain, address _escrowFactory) = + abi.decode(_data, (address, address, address, address)); if (_safeSingleton != address(0)) { safeSingleton = _safeSingleton; @@ -337,12 +301,7 @@ contract SafeSplitsEscrowZap is AccessControl, Initializable { escrowFactory = ISmartInvoiceFactory(_escrowFactory); } - emit UpdatedAddresses( - _safeSingleton, - _safeFactory, - _splitMain, - _escrowFactory - ); + emit UpdatedAddresses(_safeSingleton, _safeFactory, _splitMain, _escrowFactory); } // ADMIN @@ -377,9 +336,7 @@ contract SafeSplitsEscrowZapFactory { } event SafeSplitsEscrowZapCreated( - address indexed safeSplitsEscrowZap, - address indexed implementation, - bytes32 indexed salt + address indexed safeSplitsEscrowZap, address indexed implementation, bytes32 indexed salt ); /** @@ -387,20 +344,10 @@ contract SafeSplitsEscrowZapFactory { * @param _data addresses of the contracts used in the zap * @param _salt Salt used to create the contract address */ - function createSafeSplitsEscrowZap( - bytes calldata _data, - bytes32 _salt - ) external returns (address) { - address safeSplitEscrowZap = Clones.cloneDeterministic( - implementation, - _salt - ); + function createSafeSplitsEscrowZap(bytes calldata _data, bytes32 _salt) external returns (address) { + address safeSplitEscrowZap = Clones.cloneDeterministic(implementation, _salt); SafeSplitsEscrowZap(safeSplitEscrowZap).init(_data); - emit SafeSplitsEscrowZapCreated( - safeSplitEscrowZap, - implementation, - _salt - ); + emit SafeSplitsEscrowZapCreated(safeSplitEscrowZap, implementation, _salt); return safeSplitEscrowZap; } } diff --git a/packages/contracts/deployments/gnosis.json b/packages/contracts/deployments/gnosis.json index 27836b31..91793024 100644 --- a/packages/contracts/deployments/gnosis.json +++ b/packages/contracts/deployments/gnosis.json @@ -14,14 +14,17 @@ "implementation": ["0xA817ba0646001EcF56Cc271B7fE7e10269AE54dD"] }, "zap": { - "dao": "0xa4161dB839F84E27122398aE6337AD47765E6cD5", + "dao": "0xf02fd4286917270cb94fbc13a0f4e1ed76f7e986", "safeSingleton": "0x3E5c63644E683549055b9Be8653de26E0B4CD36E", "fallbackHandler": "0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4", "safeFactory": "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", "splitMain": "0x2ed6c4B5dA6378c7897AC67Ba9e43102Feb694EE", - "spoilsManager": "0x7C0Ca40d9806c71B5234eDD0f75E5baebE6eCE00", + "spoilsManager": "0x67aaAA970C445ef8A4F6FF1c0552Ef26cD190CD3", "factory": "0xbdB550A76cBa692F1a0B328ae1B3c932FEb7301F", "implementations": ["0xe33A71c7Cda9EDc22B40ff45c9F58F10d348B5aD"], - "instances": ["0xED148E49149Ed48331f4f34974568418dfb2964F"] + "instances": [ + "0xDF8A3D4277423887591C5F69CAf6FF148F394f68", + "0x12d56CB3E841bb1aA407C9B0D3b043641BDd23dE" + ] } } diff --git a/packages/contracts/hardhat.config.js b/packages/contracts/hardhat.config.js index 8b044bab..ec1e31ed 100644 --- a/packages/contracts/hardhat.config.js +++ b/packages/contracts/hardhat.config.js @@ -70,7 +70,7 @@ module.exports = { }, mainnet: { url: `https://mainnet.infura.io/v3/${INFURA_PROJECT_ID}`, - accounts: [`0x${PRIVATE_KEY}`], + accounts, }, hardhat: { forking: { diff --git a/packages/contracts/test/SafeSplitsDaoEscrowZap.js b/packages/contracts/test/SafeSplitsDaoEscrowZap.js index 6e8a0b78..bf9e7e51 100644 --- a/packages/contracts/test/SafeSplitsDaoEscrowZap.js +++ b/packages/contracts/test/SafeSplitsDaoEscrowZap.js @@ -26,6 +26,7 @@ const ZAP_DATA = { saltNonce: Math.floor(new Date().getTime() / 1000), // salt nonce arbitration: 1, isDaoSplit: true, + isProjectSplit: true, token: getWrappedTokenAddress(5), escrowDeadline: Math.floor(new Date().getTime() / 1000) + 30 * 24 * 60 * 60, details: ethers.utils.formatBytes32String("ipfs://"), @@ -73,7 +74,7 @@ describe("SafeSplitsDaoEscrowZap", function () { const SpoilsManagerImplementation = await ethers.getContractFactory("SpoilsManager"); - spoilsMgrImplementation = await SpoilsManagerImplementation.deploy(); + const spoilsMgrImplementation = await SpoilsManagerImplementation.deploy(); await spoilsMgrImplementation.deployed(); expect(spoilsMgrImplementation.address).to.not.equal( ethers.constants.AddressZero, @@ -163,8 +164,8 @@ describe("SafeSplitsDaoEscrowZap", function () { [ZAP_DATA.threshold, ZAP_DATA.saltNonce + i], ); const encodedSplitData = ethers.utils.defaultAbiCoder.encode( - ["bool"], - [ZAP_DATA.isDaoSplit], + ["bool", "bool"], + [ZAP_DATA.isProjectSplit, ZAP_DATA.isDaoSplit], ); const encodedEscrowData = ethers.utils.defaultAbiCoder.encode( [ @@ -186,13 +187,12 @@ describe("SafeSplitsDaoEscrowZap", function () { ZAP_DATA.details, ], ); - const SafeSplitsEscrowZapCreateReceipt = await zap[ - "createSafeSplitEscrow(address[],uint32[],uint256[],bytes,bytes,bytes)" - ]( + const SafeSplitsEscrowZapCreateReceipt = await zap.createSafeSplitEscrow( ZAP_DATA.owners, ZAP_DATA.percentAllocations, ZAP_DATA.milestoneAmounts, encodedSafeData, + ethers.constants.AddressZero, encodedSplitData, encodedEscrowData, ); @@ -223,14 +223,14 @@ describe("SafeSplitsDaoEscrowZap", function () { it("Should deploy a Zap instance", async function () { expect(zap.address).to.not.equal(ethers.constants.AddressZero); - expect(await zap.getAddresses()).to.deep.equal([ - zapData.safeSingleton, - ZAP_DATA.fallbackHandler, - zapData.safeFactory, - zapData.splitMain, - getFactory(chainId), + expect(await zap.safeSingleton()).to.equal(zapData.safeSingleton); + expect(await zap.safeFactory()).to.equal(zapData.safeFactory); + expect(await zap.splitMain()).to.equal(zapData.splitMain); + expect(await zap.spoilsManager()).to.equal(spoilsManager.address); + expect(await zap.escrowFactory()).to.equal(getFactory(chainId)); + expect(await zap.wrappedNativeToken()).to.equal( getWrappedTokenAddress(chainId), - ]); + ); }); it("Should create a Safe", async function () { diff --git a/packages/contracts/test/SafeSplitsEscrowZap.js b/packages/contracts/test/SafeSplitsEscrowZap.js index 4ab92fc3..1d8e9131 100644 --- a/packages/contracts/test/SafeSplitsEscrowZap.js +++ b/packages/contracts/test/SafeSplitsEscrowZap.js @@ -24,6 +24,7 @@ const ZAP_DATA = { saltNonce: Math.floor(new Date().getTime() / 1000), // salt nonce arbitration: 1, isDaoSplit: false, // isDaoSplit + isProjectSplit: true, // isProjectSplit token: getWrappedTokenAddress(5), // token escrowDeadline: Math.floor(new Date().getTime() / 1000) + 30 * 24 * 60 * 60, // deadline details: ethers.utils.formatBytes32String("ipfs://"), // details @@ -103,6 +104,10 @@ describe("SafeSplitsEscrowZap", function () { ["uint256", "uint256"], [ZAP_DATA.threshold, ZAP_DATA.saltNonce + i], ); + const encodedSplitData = ethers.utils.defaultAbiCoder.encode( + ["bool"], + [ZAP_DATA.isProjectSplit], + ); const encodedEscrowData = ethers.utils.defaultAbiCoder.encode( [ "address", @@ -123,11 +128,14 @@ describe("SafeSplitsEscrowZap", function () { ZAP_DATA.details, ], ); + const SafeSplitsEscrowZapCreateReceipt = await zap.createSafeSplitEscrow( ZAP_DATA.owners, ZAP_DATA.percentAllocations, ZAP_DATA.milestoneAmounts, encodedSafeData, + ethers.constants.AddressZero, // safe address, + encodedSplitData, // split data, encodedEscrowData, ); const zapCreateTx = await SafeSplitsEscrowZapCreateReceipt.wait(); @@ -148,14 +156,13 @@ describe("SafeSplitsEscrowZap", function () { it("Should deploy a Zap instance", async function () { expect(zap.address).to.not.equal(ethers.constants.AddressZero); - expect(await zap.getAddresses()).to.deep.equal([ - zapData.safeSingleton, - ZAP_DATA.fallbackHandler, - zapData.safeFactory, - zapData.splitMain, - getFactory(chainId), + expect(await zap.safeSingleton()).to.equal(zapData.safeSingleton); + expect(await zap.safeFactory()).to.equal(zapData.safeFactory); + expect(await zap.splitMain()).to.equal(zapData.splitMain); + expect(await zap.escrowFactory()).to.equal(getFactory(chainId)); + expect(await zap.wrappedNativeToken()).to.equal( getWrappedTokenAddress(chainId), - ]); + ); }); it("Should create a Safe", async function () { diff --git a/packages/contracts/test/utils.js b/packages/contracts/test/utils.js index a86a6174..310ecdca 100644 --- a/packages/contracts/test/utils.js +++ b/packages/contracts/test/utils.js @@ -1,6 +1,7 @@ const { ethers, waffle } = require("hardhat"); const { expect } = require("chai"); +const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; const EMPTY_BYTES32 = "0x0000000000000000000000000000000000000000000000000000000000000000"; @@ -366,4 +367,5 @@ module.exports = { createInstantInvoice, createUpdatableEscrow, getLockedUpdatableEscrow, + ZERO_ADDRESS, }; From 35a912de2cc34d0cb2e5d393e3926a9af467c821 Mon Sep 17 00:00:00 2001 From: scottrepreneur Date: Mon, 11 Dec 2023 07:32:02 -0600 Subject: [PATCH 7/8] subgraph fix --- .../src/abis/01/SmartInvoiceUpdatable01.json | 39 +++++++++++++++++++ .../mappings/01/helpers/updatable-escrow.ts | 28 +++++++------ packages/subgraph/src/mappings/01/utils.ts | 27 ++++++------- packages/subgraph/subgraph.template.yaml | 8 ++-- 4 files changed, 70 insertions(+), 32 deletions(-) diff --git a/packages/subgraph/src/abis/01/SmartInvoiceUpdatable01.json b/packages/subgraph/src/abis/01/SmartInvoiceUpdatable01.json index 8f71b289..c69c09a9 100644 --- a/packages/subgraph/src/abis/01/SmartInvoiceUpdatable01.json +++ b/packages/subgraph/src/abis/01/SmartInvoiceUpdatable01.json @@ -206,6 +206,45 @@ "name": "Ruling", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "client", + "type": "address" + } + ], + "name": "UpdatedClient", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "provider", + "type": "address" + } + ], + "name": "UpdatedProvider", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "providerReceiver", + "type": "address" + } + ], + "name": "UpdatedProviderReceiver", + "type": "event" + }, { "anonymous": false, "inputs": [ diff --git a/packages/subgraph/src/mappings/01/helpers/updatable-escrow.ts b/packages/subgraph/src/mappings/01/helpers/updatable-escrow.ts index abd7b59d..a6ffca19 100644 --- a/packages/subgraph/src/mappings/01/helpers/updatable-escrow.ts +++ b/packages/subgraph/src/mappings/01/helpers/updatable-escrow.ts @@ -1,31 +1,29 @@ import { Address, log } from '@graphprotocol/graph-ts'; import { Invoice } from '../../../types/schema'; -import { SmartInvoiceEscrow01 } from '../../../types/templates/SmartInvoiceEscrow01/SmartInvoiceEscrow01'; import { InvoiceObject } from '../utils'; import { SmartInvoiceUpdatable01 } from '../../../types/templates/SmartInvoiceEscrow01/SmartInvoiceUpdatable01'; import { handleIpfsDetails } from './ipfs'; function fetchEscrowInfo(address: Address): InvoiceObject { - let invoiceInstance = SmartInvoiceEscrow01.bind(address); let updatableInstance = SmartInvoiceUpdatable01.bind(address); let invoiceObject = new InvoiceObject(); - let client = invoiceInstance.try_client(); - let provider = invoiceInstance.try_provider(); + let client = updatableInstance.try_client(); + let provider = updatableInstance.try_provider(); let providerReceiver = updatableInstance.try_providerReceiver(); - let resolverType = invoiceInstance.try_resolverType(); - let resolver = invoiceInstance.try_resolver(); - let resolutionRate = invoiceInstance.try_resolutionRate(); - let token = invoiceInstance.try_token(); - let locked = invoiceInstance.try_locked(); - let milestone = invoiceInstance.try_milestone(); - let total = invoiceInstance.try_total(); - let released = invoiceInstance.try_released(); - let terminationTime = invoiceInstance.try_terminationTime(); - let details = invoiceInstance.try_details(); - let disputeId = invoiceInstance.try_disputeId(); + let resolverType = updatableInstance.try_resolverType(); + let resolver = updatableInstance.try_resolver(); + let resolutionRate = updatableInstance.try_resolutionRate(); + let token = updatableInstance.try_token(); + let locked = updatableInstance.try_locked(); + let milestone = updatableInstance.try_milestone(); + let total = updatableInstance.try_total(); + let released = updatableInstance.try_released(); + let terminationTime = updatableInstance.try_terminationTime(); + let details = updatableInstance.try_details(); + let disputeId = updatableInstance.try_disputeId(); if (!client.reverted) { invoiceObject.client = client.value; diff --git a/packages/subgraph/src/mappings/01/utils.ts b/packages/subgraph/src/mappings/01/utils.ts index fd208cb7..6a370b84 100644 --- a/packages/subgraph/src/mappings/01/utils.ts +++ b/packages/subgraph/src/mappings/01/utils.ts @@ -88,19 +88,20 @@ export function addQm(a: ByteArray): ByteArray { } export function updateInvoice(address: Address, invoice: Invoice): Invoice { - if (invoice != null) { - let type = invoice.invoiceType; - if (type != null) { - if (type == 'escrow') { - invoice = updateEscrowInfo(address, invoice); - } else if (type == 'split-escrow') { - invoice = updateSplitEscrowInfo(address, invoice); - } else if (type == 'updatable') { - invoice = updateUpdatableInfo(address, invoice); - } else { - invoice = updateInstantInfo(address, invoice); - } - } + if (invoice == null) return invoice; + + let type = invoice.invoiceType; + if (type == null) return invoice; + + if (type == 'escrow') { + invoice = updateEscrowInfo(address, invoice); + } else if (type == 'split-escrow') { + invoice = updateSplitEscrowInfo(address, invoice); + } else if (type == 'updatable') { + invoice = updateUpdatableInfo(address, invoice); + } else { + invoice = updateInstantInfo(address, invoice); } + return invoice; } diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml index 2751bcbe..3748d292 100644 --- a/packages/subgraph/subgraph.template.yaml +++ b/packages/subgraph/subgraph.template.yaml @@ -17,7 +17,7 @@ dataSources: startBlock: {{startBlock}} mapping: kind: ethereum/events - apiVersion: 0.0.5 + apiVersion: 0.0.6 language: wasm/assemblyscript entities: - Invoice @@ -36,7 +36,7 @@ dataSources: - name: SmartInvoiceSplitEscrow{{factoryName}} file: ./src/abis/{{factoryName}}/SmartInvoiceSplitEscrow{{factoryName}}.json - name: SmartInvoiceUpdatable{{factoryName}} - file: ./src/abis/{{factoryName}}/SmartInvoiceSplitEscrow{{factoryName}}.json + file: ./src/abis/{{factoryName}}/SmartInvoiceUpdatable{{factoryName}}.json {{/v01}} - name: SmartInvoiceFactory{{factoryName}} file: ./src/abis/{{factoryName}}/SmartInvoiceFactory{{factoryName}}.json @@ -63,7 +63,7 @@ templates: abi: SmartInvoice{{factoryName}} mapping: kind: ethereum/events - apiVersion: 0.0.5 + apiVersion: 0.0.6 language: wasm/assemblyscript entities: - Invoice @@ -212,7 +212,7 @@ templates: - event: MilestonesAdded(indexed address,indexed address,uint256[]) handler: handleMilestonesAdded file: ./src/mappings/{{factoryName}}/invoice.ts - - kind: ethereum/contract + - kind: ethereum/contract name: SmartInvoiceUpdatable{{factoryName}} # prettier-ignore network: {{network}} From b820775c407d9023a85d9c6f8600ead6aa18bf42 Mon Sep 17 00:00:00 2001 From: scottrepreneur Date: Thu, 14 Dec 2023 17:53:12 -0600 Subject: [PATCH 8/8] gnosis subgraph fix --- .../contracts/SafeSplitsDaoEscrowZap.sol | 62 +++---- .../contracts/test/SafeSplitsDaoEscrowZap.js | 156 +++++++++++++++++- packages/dapp/constants/config.js | 2 +- packages/subgraph/src/mappings/01/factory.ts | 2 +- .../subgraph/src/mappings/01/helpers/ipfs.ts | 14 +- 5 files changed, 197 insertions(+), 39 deletions(-) diff --git a/packages/contracts/contracts/SafeSplitsDaoEscrowZap.sol b/packages/contracts/contracts/SafeSplitsDaoEscrowZap.sol index 7a76b167..c71b1c7c 100644 --- a/packages/contracts/contracts/SafeSplitsDaoEscrowZap.sol +++ b/packages/contracts/contracts/SafeSplitsDaoEscrowZap.sol @@ -51,37 +51,37 @@ contract SafeSplitsDaoEscrowZap is SafeSplitsEscrowZap { } } - if (daoSplit) { - // prepare arrays - address[] memory daoSplitRecipients = new address[](2); - uint32[] memory daoSplitPercentAllocations = new uint32[](2); - - // dao split recipients - address daoReceiver = spoilsManager.receiver(); - - // dao split amounts - uint32 daoSplitAmount = spoilsManager.getSpoils(); - uint32 projectSplitAmount = (100 * spoilsManager.SPLIT_PERCENTAGE_SCALE()) - (daoSplitAmount); - - // sort the addresses into the correct order - if (uint160(daoReceiver) < uint160(_daoZapData.zapData.projectTeamSplit)) { - daoSplitRecipients[0] = daoReceiver; - daoSplitRecipients[1] = _daoZapData.zapData.projectTeamSplit; - daoSplitPercentAllocations[0] = daoSplitAmount; - daoSplitPercentAllocations[1] = projectSplitAmount; - } else { - daoSplitRecipients[0] = _daoZapData.zapData.projectTeamSplit; - daoSplitRecipients[1] = daoReceiver; - daoSplitPercentAllocations[0] = projectSplitAmount; - daoSplitPercentAllocations[1] = daoSplitAmount; - } + if (!daoSplit) return _daoZapData; + + // prepare arrays + address[] memory daoSplitRecipients = new address[](2); + uint32[] memory daoSplitPercentAllocations = new uint32[](2); + + // dao split recipients + address daoReceiver = spoilsManager.receiver(); + + // dao split amounts + uint32 daoSplitAmount = spoilsManager.getSpoils(); + uint32 projectSplitAmount = (100 * spoilsManager.SPLIT_PERCENTAGE_SCALE()) - (daoSplitAmount); + + // sort the addresses into the correct order + if (uint160(daoReceiver) < uint160(_daoZapData.zapData.projectTeamSplit)) { + daoSplitRecipients[0] = daoReceiver; + daoSplitRecipients[1] = _daoZapData.zapData.projectTeamSplit; + daoSplitPercentAllocations[0] = daoSplitAmount; + daoSplitPercentAllocations[1] = projectSplitAmount; + } else { + daoSplitRecipients[0] = _daoZapData.zapData.projectTeamSplit; + daoSplitRecipients[1] = daoReceiver; + daoSplitPercentAllocations[0] = projectSplitAmount; + daoSplitPercentAllocations[1] = daoSplitAmount; + } - // (recipients array, percent allocations array, no distributor fee, safe address) - _daoZapData.daoSplit = - splitMain.createSplit(daoSplitRecipients, daoSplitPercentAllocations, distributorFee, dao); - if (_daoZapData.daoSplit == address(0)) { - revert DaoSplitCreationFailed(); - } + // (recipients array, percent allocations array, no distributor fee, safe address) + _daoZapData.daoSplit = + splitMain.createSplit(daoSplitRecipients, daoSplitPercentAllocations, distributorFee, dao); + if (_daoZapData.daoSplit == address(0)) { + revert DaoSplitCreationFailed(); } return _daoZapData; @@ -115,10 +115,12 @@ contract SafeSplitsDaoEscrowZap is SafeSplitsEscrowZap { daoSplit: address(0) }); + // optionally deploy safe if (daoZapData.zapData.safe == address(0)) { daoZapData.zapData = _deploySafe(_owners, _safeData, daoZapData.zapData); } + // create split(s) daoZapData = _createSplit(_owners, _percentAllocations, _splitsData, daoZapData); address[] memory escrowParams = _handleEscrowParams(daoZapData); diff --git a/packages/contracts/test/SafeSplitsDaoEscrowZap.js b/packages/contracts/test/SafeSplitsDaoEscrowZap.js index bf9e7e51..046f259b 100644 --- a/packages/contracts/test/SafeSplitsDaoEscrowZap.js +++ b/packages/contracts/test/SafeSplitsDaoEscrowZap.js @@ -1,7 +1,7 @@ const { expect } = require("chai"); const { ethers } = require("hardhat"); -const { currentTimestamp } = require("./utils"); +const { currentTimestamp, ZERO_ADDRESS } = require("./utils"); const { getZapData, @@ -52,6 +52,9 @@ describe("SafeSplitsDaoEscrowZap", function () { let escrow; let token; let receiver; + let encodedSafeData; + let encodedSplitData; + let encodedEscrowData; let i = 0; before(async function () { @@ -157,17 +160,16 @@ describe("SafeSplitsDaoEscrowZap", function () { beforeEach(async function () { i++; // increment to avoid nonce collisions in Create2 deployments - // create with zap - const encodedSafeData = ethers.utils.defaultAbiCoder.encode( + encodedSafeData = ethers.utils.defaultAbiCoder.encode( ["uint256", "uint256"], [ZAP_DATA.threshold, ZAP_DATA.saltNonce + i], ); - const encodedSplitData = ethers.utils.defaultAbiCoder.encode( + encodedSplitData = ethers.utils.defaultAbiCoder.encode( ["bool", "bool"], [ZAP_DATA.isProjectSplit, ZAP_DATA.isDaoSplit], ); - const encodedEscrowData = ethers.utils.defaultAbiCoder.encode( + encodedEscrowData = ethers.utils.defaultAbiCoder.encode( [ "address", "uint32", @@ -360,5 +362,149 @@ describe("SafeSplitsDaoEscrowZap", function () { ); }); + it("Should let the deployer skip the safe deploy", async function () { + const localEncodedEscrowData = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "uint32", + "address", + "address", + "uint256", + "uint256", + "bytes32", + ], + [ + ZAP_DATA.client, + ZAP_DATA.arbitration, + ZAP_DATA.resolver, + ZAP_DATA.token, + ZAP_DATA.escrowDeadline, + ZAP_DATA.saltNonce + 200 * i, + ZAP_DATA.details, + ], + ); + const SafeSplitsEscrowZapCreateReceipt = await zap.createSafeSplitEscrow( + ZAP_DATA.owners, + ZAP_DATA.percentAllocations, + ZAP_DATA.milestoneAmounts, + encodedSafeData, + deployer.address, + encodedSplitData, + localEncodedEscrowData, + ); + const zapCreateTx = await SafeSplitsEscrowZapCreateReceipt.wait(); + const zapCreatedEvent = zapCreateTx.events.find( + e => e.event === "SafeSplitsDaoEscrowCreated", + ); + const [safeAddress, teamSplitAddress, daoSplitAddress, escrowAddress] = + ethers.utils.defaultAbiCoder.decode( + ["address", "address", "address", "address"], + zapCreatedEvent.data, + ); + expect(safeAddress).to.equal(deployer.address); + }); + + it("Should let the deployer skip the team split", async function () { + const localEncodedSafeData = ethers.utils.defaultAbiCoder.encode( + ["uint256", "uint256"], + [ZAP_DATA.threshold, ZAP_DATA.saltNonce + 100 * i], + ); + const localEncodedSplitData = ethers.utils.defaultAbiCoder.encode( + ["bool", "bool"], + [false, true], + ); + const localEncodedEscrowData = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "uint32", + "address", + "address", + "uint256", + "uint256", + "bytes32", + ], + [ + ZAP_DATA.client, + ZAP_DATA.arbitration, + ZAP_DATA.resolver, + ZAP_DATA.token, + ZAP_DATA.escrowDeadline, + ZAP_DATA.saltNonce + 100 * i, + ZAP_DATA.details, + ], + ); + const SafeSplitsEscrowZapCreateReceipt = await zap.createSafeSplitEscrow( + ZAP_DATA.owners, + ZAP_DATA.percentAllocations, + ZAP_DATA.milestoneAmounts, + localEncodedSafeData, + ethers.constants.AddressZero, + localEncodedSplitData, + localEncodedEscrowData, + ); + const zapCreateTx = await SafeSplitsEscrowZapCreateReceipt.wait(); + const zapCreatedEvent = zapCreateTx.events.find( + e => e.event === "SafeSplitsDaoEscrowCreated", + ); + const [safeAddress, teamSplitAddress, daoSplitAddress, escrowAddress] = + ethers.utils.defaultAbiCoder.decode( + ["address", "address", "address", "address"], + zapCreatedEvent.data, + ); + + expect(teamSplitAddress).to.equal(safeAddress); + }); + + it("Should let the deployer skip the dao split", async function () { + const localEncodedSafeData = ethers.utils.defaultAbiCoder.encode( + ["uint256", "uint256"], + [ZAP_DATA.threshold, ZAP_DATA.saltNonce + 300 * i], + ); + const localEncodedSplitData = ethers.utils.defaultAbiCoder.encode( + ["bool", "bool"], + [true, false], + ); + const localEncodedEscrowData = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "uint32", + "address", + "address", + "uint256", + "uint256", + "bytes32", + ], + [ + ZAP_DATA.client, + ZAP_DATA.arbitration, + ZAP_DATA.resolver, + ZAP_DATA.token, + ZAP_DATA.escrowDeadline, + ZAP_DATA.saltNonce + 300 * i, + ZAP_DATA.details, + ], + ); + const SafeSplitsEscrowZapCreateReceipt = await zap.createSafeSplitEscrow( + ZAP_DATA.owners, + ZAP_DATA.percentAllocations, + ZAP_DATA.milestoneAmounts, + localEncodedSafeData, + ethers.constants.AddressZero, + localEncodedSplitData, + localEncodedEscrowData, + ); + const zapCreateTx = await SafeSplitsEscrowZapCreateReceipt.wait(); + const zapCreatedEvent = zapCreateTx.events.find( + e => e.event === "SafeSplitsDaoEscrowCreated", + ); + const [safeAddress, teamSplitAddress, daoSplitAddress, escrowAddress] = + ethers.utils.defaultAbiCoder.decode( + ["address", "address", "address", "address"], + zapCreatedEvent.data, + ); + + expect(daoSplitAddress).to.equal(ZERO_ADDRESS); + }); + // it should let the safe update the split - handle from Safe UI for now }); diff --git a/packages/dapp/constants/config.js b/packages/dapp/constants/config.js index b3d33ebe..edb64cef 100644 --- a/packages/dapp/constants/config.js +++ b/packages/dapp/constants/config.js @@ -21,7 +21,7 @@ export const CONFIG = { }, }, 100: { - SUBGRAPH: 'psparacino/v1-xdai-smart-invoices', + SUBGRAPH: 'scottrepreneur/smart-invoice-gnosis', WRAPPED_NATIVE_TOKEN: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d'.toLowerCase(), INVOICE_FACTORY: diff --git a/packages/subgraph/src/mappings/01/factory.ts b/packages/subgraph/src/mappings/01/factory.ts index 0a738170..e776bdb9 100644 --- a/packages/subgraph/src/mappings/01/factory.ts +++ b/packages/subgraph/src/mappings/01/factory.ts @@ -46,7 +46,7 @@ export function handleLogNewInvoice(event: LogNewInvoiceEvent): void { SmartInvoiceSplitEscrow01.create(event.params.invoice); } else if (invoice.invoiceType == 'updatable') { SmartInvoiceUpdatable01.create(event.params.invoice); - } else { + } else if (invoice.invoiceType == 'instant') { SmartInvoiceInstant01.create(event.params.invoice); } diff --git a/packages/subgraph/src/mappings/01/helpers/ipfs.ts b/packages/subgraph/src/mappings/01/helpers/ipfs.ts index 26fc43a4..576e0bf0 100644 --- a/packages/subgraph/src/mappings/01/helpers/ipfs.ts +++ b/packages/subgraph/src/mappings/01/helpers/ipfs.ts @@ -5,6 +5,7 @@ import { json, log, JSONValue, + JSONValueKind, } from '@graphprotocol/graph-ts'; import { Agreement } from '../../../types/schema'; @@ -54,6 +55,7 @@ export function handleIpfsDetails( invoiceObject: InvoiceObject, ): InvoiceObject { invoiceObject.details = details; + let hexHash = changetype(addQm(invoiceObject.details)); let base58Hash = hexHash.toBase58(); invoiceObject.ipfsHash = base58Hash.toString(); @@ -87,11 +89,19 @@ export function handleIpfsDetails( } } let startDate = data.get('startDate'); - if (startDate != null && !startDate.isNull()) { + if ( + startDate != null && + !startDate.isNull() && + startDate.kind == JSONValueKind.NUMBER + ) { invoiceObject.startDate = startDate.toBigInt(); } let endDate = data.get('endDate'); - if (endDate != null && !endDate.isNull()) { + if ( + endDate != null && + !endDate.isNull() && + endDate.kind == JSONValueKind.NUMBER + ) { invoiceObject.endDate = endDate.toBigInt(); }