tapimo 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.d.ts +2095 -2111
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +0 -1
- package/dist/App.js.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +166 -166
- package/dist/apps/data/App.d.ts +4084 -3845
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +270 -270
- package/dist/apps/data/routes/addresses.d.ts +248 -17
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +272 -2
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +114 -2
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +123 -123
- package/dist/apps/data/routes/earn.d.ts +65 -3
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +259 -14
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/rpc.d.ts +31 -31
- package/dist/apps/data/routes/tokens.d.ts +454 -454
- package/dist/apps/data/routes/transfers.d.ts +81 -81
- package/dist/apps/funding/App.d.ts +40 -299
- package/dist/apps/funding/App.d.ts.map +1 -1
- package/dist/apps/funding/App.js +20 -5
- package/dist/apps/funding/App.js.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts +43 -434
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.js +21 -103
- package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
- package/dist/apps/funding/routes/quotes.d.ts +89 -89
- package/dist/apps/funding/routes/transfers.js +5 -5
- package/dist/apps/funding/routes/transfers.js.map +1 -1
- package/dist/apps/management/routes/invitations.d.ts +134 -134
- package/dist/apps/management/routes/orgs.d.ts +98 -98
- package/dist/apps/management/routes/verified-token-requests.d.ts +83 -83
- package/dist/apps/mpp/App.d.ts +44 -44
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +8 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/tables/fundingDeposits.d.ts +18 -1
- package/dist/db/tables/fundingDeposits.d.ts.map +1 -1
- package/dist/db/tables/fundingDeposits.js +46 -2
- package/dist/db/tables/fundingDeposits.js.map +1 -1
- package/dist/internal/Auth.d.ts +4 -0
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +11 -2
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/funding/Provider.d.ts +6 -6
- package/dist/internal/funding/Provider.d.ts.map +1 -1
- package/dist/internal/funding/Reconciliation.d.ts.map +1 -1
- package/dist/internal/funding/Reconciliation.js +101 -16
- package/dist/internal/funding/Reconciliation.js.map +1 -1
- package/dist/internal/funding/providers/relay.d.ts.map +1 -1
- package/dist/internal/funding/providers/relay.js +6 -2
- package/dist/internal/funding/providers/relay.js.map +1 -1
- package/package.json +1 -1
- package/src/App.test.ts +32 -0
- package/src/App.ts +4 -1
- package/src/Client.test-d.ts +56 -33
- package/src/apps/composition.test.ts +39 -10
- package/src/apps/data/routes/balances.test.ts +42 -0
- package/src/apps/data/routes/balances.ts +218 -85
- package/src/apps/data/routes/earn.test.ts +89 -9
- package/src/apps/data/routes/earn.ts +355 -14
- package/src/apps/funding/App.ts +20 -5
- package/src/apps/funding/routes/deposit-addresses.test.ts +43 -22
- package/src/apps/funding/routes/deposit-addresses.ts +34 -117
- package/src/apps/funding/routes/transfers.test.ts +6 -25
- package/src/apps/funding/routes/transfers.ts +5 -5
- package/src/db/Db.ts +9 -0
- package/src/db/tables/fundingDeposits.test.ts +101 -0
- package/src/db/tables/fundingDeposits.ts +71 -2
- package/src/internal/Auth.test.ts +28 -0
- package/src/internal/Auth.ts +15 -1
- package/src/internal/funding/Provider.ts +4 -4
- package/src/internal/funding/Reconciliation.test.ts +292 -54
- package/src/internal/funding/Reconciliation.ts +160 -53
- package/src/internal/funding/SourceObservation.test.ts +2 -2
- package/src/internal/funding/providers/relay.ts +7 -2
|
@@ -31,6 +31,8 @@ const redeemRequestedSignature = 'event RedeemRequested(bytes32 indexed requestI
|
|
|
31
31
|
const venueSharesDepositedSignature = 'event VenueSharesDeposited(address indexed caller,address indexed receiver,uint256 requestedVenueShares,uint256 receivedVenueShares,uint256 earnShares)';
|
|
32
32
|
const maxScannedDeployments = 250;
|
|
33
33
|
const scanLimit = 50;
|
|
34
|
+
/** Block boundary that includes all indexed history. */
|
|
35
|
+
const beforeFirstBlockNumber = -1;
|
|
34
36
|
/** Vault TVL is reported in USD only; the API exposes no denomination parameter. */
|
|
35
37
|
const tvlDenomination = 'USD';
|
|
36
38
|
/** `Valuation.valuationFor` floors to 6 dp, so 6 is the precision a valued amount carries. */
|
|
@@ -170,8 +172,8 @@ export var schema;
|
|
|
170
172
|
id: Schema.Address.check(z.describe('Stable resource ID for these vault earnings, equal to the account address.'), z.meta({ examples: ['0x68f94cfca22e5969c0553bbeab00a2acde88939b'] })),
|
|
171
173
|
});
|
|
172
174
|
const earningsPeriod = z
|
|
173
|
-
.enum(['active', 'lifetime'])
|
|
174
|
-
.check(z.describe('Earnings period to calculate.'), z.meta({ examples: ['lifetime'] }));
|
|
175
|
+
.enum(['30d', 'active', 'lifetime'])
|
|
176
|
+
.check(z.describe('Earnings period to calculate: trailing 30 days, shares still held, or lifetime history.'), z.meta({ examples: ['lifetime'] }));
|
|
175
177
|
const earnings = z.union([
|
|
176
178
|
z.extend(earningsBase, {
|
|
177
179
|
lifetimeEarnings: z
|
|
@@ -195,16 +197,27 @@ export var schema;
|
|
|
195
197
|
.literal('complete')
|
|
196
198
|
.check(z.describe('Earnings include a complete asset-denominated cost basis.'), z.meta({ examples: ['complete'] })),
|
|
197
199
|
}),
|
|
200
|
+
z.extend(earningsBase, {
|
|
201
|
+
period: z
|
|
202
|
+
.literal('30d')
|
|
203
|
+
.check(z.describe('Returns cash-flow-adjusted earnings over the trailing 30 days.'), z.meta({ examples: ['30d'] })),
|
|
204
|
+
status: z
|
|
205
|
+
.literal('complete')
|
|
206
|
+
.check(z.describe('Earnings include a complete asset-denominated cost basis.'), z.meta({ examples: ['complete'] })),
|
|
207
|
+
windowEarnings: z
|
|
208
|
+
.string()
|
|
209
|
+
.check(z.regex(/^-?\d+$/), z.describe('Ending share value plus realized assets, minus deposits and opening share value, over the trailing 30 days.'), z.meta({ examples: ['0'] })),
|
|
210
|
+
}),
|
|
198
211
|
z.extend(earningsBase, {
|
|
199
212
|
period: earningsPeriod,
|
|
200
213
|
status: z
|
|
201
214
|
.literal('incomplete_cost_basis')
|
|
202
|
-
.check(z.describe('Earnings are unavailable when indexed activity cannot reconstruct the
|
|
215
|
+
.check(z.describe('Earnings are unavailable when indexed activity cannot reconstruct the asset cost basis for the requested period.'), z.meta({ examples: ['incomplete_cost_basis'] })),
|
|
203
216
|
}),
|
|
204
217
|
z.extend(earningsBase, {
|
|
205
218
|
period: z
|
|
206
|
-
.
|
|
207
|
-
.check(z.describe('
|
|
219
|
+
.enum(['30d', 'lifetime'])
|
|
220
|
+
.check(z.describe('Earnings period with an unresolved async redemption.'), z.meta({ examples: ['lifetime'] })),
|
|
208
221
|
status: z
|
|
209
222
|
.literal('pending_redemption')
|
|
210
223
|
.check(z.describe('Earnings are unavailable while an async redemption remains open.'), z.meta({ examples: ['pending_redemption'] })),
|
|
@@ -510,7 +523,7 @@ export function earn(options = {}) {
|
|
|
510
523
|
code: 'query_invalid',
|
|
511
524
|
message: 'Invalid query parameters',
|
|
512
525
|
}), OpenApi.describeRoute({
|
|
513
|
-
description: 'Gets an account’s indexed asset value and earnings for lifetime history or shares still held.',
|
|
526
|
+
description: 'Gets an account’s indexed asset value and earnings for lifetime history, the trailing 30 days, or shares still held.',
|
|
514
527
|
operationId: 'getEarnVaultEarnings',
|
|
515
528
|
responses: OpenApi.responses({
|
|
516
529
|
errors: {
|
|
@@ -538,7 +551,7 @@ export function earn(options = {}) {
|
|
|
538
551
|
}), Cache.response({
|
|
539
552
|
cacheControl: Cache.policies.state,
|
|
540
553
|
key: (c) => Cache.urlKey(c, schema.getEarnVaultEarnings.Query),
|
|
541
|
-
name: 'tempo-api:earn-vault-earnings:
|
|
554
|
+
name: 'tempo-api:earn-vault-earnings:v3',
|
|
542
555
|
}), async (c) => {
|
|
543
556
|
if (Auth.narrowAccess)
|
|
544
557
|
return Auth.paidAccessError(c);
|
|
@@ -660,7 +673,17 @@ export function earn(options = {}) {
|
|
|
660
673
|
export async function getVaultEarnings(c, options) {
|
|
661
674
|
const client = c.get('getClient')(options.chainId);
|
|
662
675
|
const tidx = c.get('getTidx')(options.chainId);
|
|
663
|
-
const
|
|
676
|
+
const block = await getLatestIndexedBlock(tidx);
|
|
677
|
+
const blockNumber = block.number;
|
|
678
|
+
if (options.period === '30d')
|
|
679
|
+
return getWindowVaultEarnings(c, {
|
|
680
|
+
account: options.account,
|
|
681
|
+
blockNumber,
|
|
682
|
+
chainId: options.chainId,
|
|
683
|
+
period: options.period,
|
|
684
|
+
timestamp: block.timestamp,
|
|
685
|
+
vault: options.vault,
|
|
686
|
+
});
|
|
664
687
|
const position = client.earn.getPosition({
|
|
665
688
|
account: options.account,
|
|
666
689
|
blockNumber: BigInt(blockNumber),
|
|
@@ -694,6 +717,7 @@ export async function getVaultEarnings(c, options) {
|
|
|
694
717
|
getVaultEarningsHistory(tidx, {
|
|
695
718
|
account: options.account,
|
|
696
719
|
blockNumber,
|
|
720
|
+
startBlockNumber: beforeFirstBlockNumber,
|
|
697
721
|
vault: options.vault,
|
|
698
722
|
}),
|
|
699
723
|
position,
|
|
@@ -702,6 +726,7 @@ export async function getVaultEarnings(c, options) {
|
|
|
702
726
|
account: options.account,
|
|
703
727
|
blockNumber,
|
|
704
728
|
shareToken: current.shareToken,
|
|
729
|
+
startBlockNumber: beforeFirstBlockNumber,
|
|
705
730
|
vault: options.vault,
|
|
706
731
|
});
|
|
707
732
|
const base = {
|
|
@@ -718,15 +743,105 @@ export async function getVaultEarnings(c, options) {
|
|
|
718
743
|
const lifetimeEarnings = current.value + history.redeemed + history.withdrewExact + history.finalized - history.deposited;
|
|
719
744
|
return { ...base, lifetimeEarnings: lifetimeEarnings.toString(), status: 'complete' };
|
|
720
745
|
}
|
|
746
|
+
/** Reads cash-flow-adjusted earnings over a trailing indexed window. */
|
|
747
|
+
async function getWindowVaultEarnings(c, options) {
|
|
748
|
+
const client = c.get('getClient')(options.chainId);
|
|
749
|
+
const tidx = c.get('getTidx')(options.chainId);
|
|
750
|
+
const [current, startBlockNumber] = await Promise.all([
|
|
751
|
+
client.earn.getPosition({
|
|
752
|
+
account: options.account,
|
|
753
|
+
blockNumber: BigInt(options.blockNumber),
|
|
754
|
+
vault: options.vault,
|
|
755
|
+
}),
|
|
756
|
+
getWindowStartBlockNumber(tidx, { days: 30, timestamp: options.timestamp }),
|
|
757
|
+
]);
|
|
758
|
+
const [externalShareTransfer, history, opening] = await Promise.all([
|
|
759
|
+
hasExternalShareTransfer(tidx, {
|
|
760
|
+
account: options.account,
|
|
761
|
+
blockNumber: options.blockNumber,
|
|
762
|
+
shareToken: current.shareToken,
|
|
763
|
+
startBlockNumber,
|
|
764
|
+
vault: options.vault,
|
|
765
|
+
}),
|
|
766
|
+
getVaultEarningsHistory(tidx, {
|
|
767
|
+
account: options.account,
|
|
768
|
+
blockNumber: options.blockNumber,
|
|
769
|
+
startBlockNumber,
|
|
770
|
+
vault: options.vault,
|
|
771
|
+
}),
|
|
772
|
+
getWindowShareState(tidx, {
|
|
773
|
+
account: options.account,
|
|
774
|
+
blockNumber: options.blockNumber,
|
|
775
|
+
shareToken: current.shareToken,
|
|
776
|
+
startBlockNumber,
|
|
777
|
+
vault: options.vault,
|
|
778
|
+
}),
|
|
779
|
+
]);
|
|
780
|
+
const base = {
|
|
781
|
+
account: options.account,
|
|
782
|
+
assetToken: current.assetToken,
|
|
783
|
+
currentValue: current.value.toString(),
|
|
784
|
+
id: options.account,
|
|
785
|
+
period: options.period,
|
|
786
|
+
};
|
|
787
|
+
if (opening === undefined ||
|
|
788
|
+
externalShareTransfer ||
|
|
789
|
+
history.incompleteCostBasis ||
|
|
790
|
+
opening.crossBoundaryRedemption ||
|
|
791
|
+
opening.endShares !== current.shareBalance)
|
|
792
|
+
return { ...base, status: 'incomplete_cost_basis' };
|
|
793
|
+
if (history.pendingRedemption)
|
|
794
|
+
return { ...base, status: 'pending_redemption' };
|
|
795
|
+
const openingValue = opening.startShares === 0n
|
|
796
|
+
? 0n
|
|
797
|
+
: await client.earn.getRedeemQuote({
|
|
798
|
+
blockNumber: BigInt(startBlockNumber),
|
|
799
|
+
shareAmount: opening.startShares,
|
|
800
|
+
vault: options.vault,
|
|
801
|
+
});
|
|
802
|
+
const windowEarnings = calculateWindowEarnings({
|
|
803
|
+
deposited: history.deposited,
|
|
804
|
+
endingValue: current.value,
|
|
805
|
+
finalized: history.finalized,
|
|
806
|
+
openingValue,
|
|
807
|
+
redeemed: history.redeemed,
|
|
808
|
+
withdrewExact: history.withdrewExact,
|
|
809
|
+
});
|
|
810
|
+
return { ...base, status: 'complete', windowEarnings: windowEarnings.toString() };
|
|
811
|
+
}
|
|
812
|
+
/** Calculates cash-flow-adjusted earnings between two position snapshots. */
|
|
813
|
+
export function calculateWindowEarnings(options) {
|
|
814
|
+
return (options.endingValue +
|
|
815
|
+
options.redeemed +
|
|
816
|
+
options.withdrewExact +
|
|
817
|
+
options.finalized -
|
|
818
|
+
options.deposited -
|
|
819
|
+
options.openingValue);
|
|
820
|
+
}
|
|
721
821
|
/** Reads the latest block whose indexed logs back the earnings calculation. */
|
|
722
|
-
async function
|
|
822
|
+
async function getLatestIndexedBlock(tidx) {
|
|
723
823
|
const result = await tidx.fetch({
|
|
724
824
|
engine: 'clickhouse',
|
|
725
|
-
query: 'SELECT num FROM blocks ORDER BY num DESC LIMIT 1',
|
|
825
|
+
query: 'SELECT num, timestamp FROM blocks ORDER BY num DESC LIMIT 1',
|
|
726
826
|
});
|
|
727
|
-
const
|
|
728
|
-
|
|
827
|
+
const number = Value.toNumber(result.rows[0]?.['num']);
|
|
828
|
+
const timestamp = Value.toIsoDateTime(result.rows[0]?.['timestamp']);
|
|
829
|
+
if (number === undefined || timestamp === undefined)
|
|
729
830
|
throw new Error('TIDX returned no indexed block.');
|
|
831
|
+
return { number, timestamp };
|
|
832
|
+
}
|
|
833
|
+
/** Resolves the last indexed block at or before a trailing-day boundary. */
|
|
834
|
+
async function getWindowStartBlockNumber(tidx, options) {
|
|
835
|
+
const cutoff = new Date(Date.parse(options.timestamp) - Ttl.days(options.days)).toISOString();
|
|
836
|
+
const result = await tidx.fetch({
|
|
837
|
+
query: `SELECT num FROM blocks WHERE timestamp <= '${cutoff}' ORDER BY num DESC LIMIT 1`,
|
|
838
|
+
});
|
|
839
|
+
const row = result.rows[0];
|
|
840
|
+
if (!row)
|
|
841
|
+
return beforeFirstBlockNumber;
|
|
842
|
+
const blockNumber = Value.toNumber(row['num']);
|
|
843
|
+
if (blockNumber === undefined)
|
|
844
|
+
throw new Error('TIDX returned no Earn earnings boundary.');
|
|
730
845
|
return blockNumber;
|
|
731
846
|
}
|
|
732
847
|
/** Reads the indexed cash flows and exceptional states behind one earnings calculation. */
|
|
@@ -740,6 +855,7 @@ async function getVaultEarningsHistory(tidx, options) {
|
|
|
740
855
|
FROM Deposited
|
|
741
856
|
WHERE address = '${options.vault}'
|
|
742
857
|
AND receiver = '${options.account}'
|
|
858
|
+
AND block_num > ${options.startBlockNumber}
|
|
743
859
|
AND block_num <= ${options.blockNumber}
|
|
744
860
|
) AS deposited_assets,
|
|
745
861
|
(
|
|
@@ -750,6 +866,7 @@ async function getVaultEarningsHistory(tidx, options) {
|
|
|
750
866
|
AND requested."requestId" = finalized."requestId"
|
|
751
867
|
WHERE finalized.address = '${options.vault}'
|
|
752
868
|
AND requested.requester = '${options.account}'
|
|
869
|
+
AND finalized.block_num > ${options.startBlockNumber}
|
|
753
870
|
AND finalized.block_num <= ${options.blockNumber}
|
|
754
871
|
AND requested.block_num <= ${options.blockNumber}
|
|
755
872
|
) AS finalized_assets,
|
|
@@ -773,6 +890,7 @@ async function getVaultEarningsHistory(tidx, options) {
|
|
|
773
890
|
FROM Redeemed
|
|
774
891
|
WHERE address = '${options.vault}'
|
|
775
892
|
AND caller = '${options.account}'
|
|
893
|
+
AND block_num > ${options.startBlockNumber}
|
|
776
894
|
AND block_num <= ${options.blockNumber}
|
|
777
895
|
) AS redeemed_assets,
|
|
778
896
|
(
|
|
@@ -782,6 +900,7 @@ async function getVaultEarningsHistory(tidx, options) {
|
|
|
782
900
|
ON requested.address = cancelled.address
|
|
783
901
|
AND requested."requestId" = cancelled."requestId"
|
|
784
902
|
WHERE cancelled.address = '${options.vault}'
|
|
903
|
+
AND cancelled.block_num > ${options.startBlockNumber}
|
|
785
904
|
AND cancelled.block_num <= ${options.blockNumber}
|
|
786
905
|
AND requested.block_num <= ${options.blockNumber}
|
|
787
906
|
AND requested.requester != cancelled.receiver
|
|
@@ -795,6 +914,7 @@ async function getVaultEarningsHistory(tidx, options) {
|
|
|
795
914
|
FROM VenueSharesDeposited
|
|
796
915
|
WHERE address = '${options.vault}'
|
|
797
916
|
AND receiver = '${options.account}'
|
|
917
|
+
AND block_num > ${options.startBlockNumber}
|
|
798
918
|
AND block_num <= ${options.blockNumber}
|
|
799
919
|
) AS venue_deposits,
|
|
800
920
|
(
|
|
@@ -802,6 +922,7 @@ async function getVaultEarningsHistory(tidx, options) {
|
|
|
802
922
|
FROM WithdrewExact
|
|
803
923
|
WHERE address = '${options.vault}'
|
|
804
924
|
AND caller = '${options.account}'
|
|
925
|
+
AND block_num > ${options.startBlockNumber}
|
|
805
926
|
AND block_num <= ${options.blockNumber}
|
|
806
927
|
) AS withdrew_exact
|
|
807
928
|
`,
|
|
@@ -840,6 +961,93 @@ async function getVaultEarningsHistory(tidx, options) {
|
|
|
840
961
|
withdrewExact: BigInt(withdrewExact),
|
|
841
962
|
};
|
|
842
963
|
}
|
|
964
|
+
/** Reads share balances and cross-boundary redemptions for a trailing window. */
|
|
965
|
+
async function getWindowShareState(tidx, options) {
|
|
966
|
+
const result = await tidx.fetch({
|
|
967
|
+
engine: 'clickhouse',
|
|
968
|
+
query: `
|
|
969
|
+
SELECT
|
|
970
|
+
(
|
|
971
|
+
SELECT toString(sum(toUInt256(amount)))
|
|
972
|
+
FROM token_transfers
|
|
973
|
+
WHERE token = '${options.shareToken.toLowerCase()}'
|
|
974
|
+
AND "to" = '${options.account}'
|
|
975
|
+
AND block_num <= ${options.startBlockNumber}
|
|
976
|
+
) AS received_start,
|
|
977
|
+
(
|
|
978
|
+
SELECT toString(sum(toUInt256(amount)))
|
|
979
|
+
FROM token_transfers
|
|
980
|
+
WHERE token = '${options.shareToken.toLowerCase()}'
|
|
981
|
+
AND "from" = '${options.account}'
|
|
982
|
+
AND block_num <= ${options.startBlockNumber}
|
|
983
|
+
) AS sent_start,
|
|
984
|
+
(
|
|
985
|
+
SELECT toString(sum(toUInt256(amount)))
|
|
986
|
+
FROM token_transfers
|
|
987
|
+
WHERE token = '${options.shareToken.toLowerCase()}'
|
|
988
|
+
AND "to" = '${options.account}'
|
|
989
|
+
AND block_num <= ${options.blockNumber}
|
|
990
|
+
) AS received_end,
|
|
991
|
+
(
|
|
992
|
+
SELECT toString(sum(toUInt256(amount)))
|
|
993
|
+
FROM token_transfers
|
|
994
|
+
WHERE token = '${options.shareToken.toLowerCase()}'
|
|
995
|
+
AND "from" = '${options.account}'
|
|
996
|
+
AND block_num <= ${options.blockNumber}
|
|
997
|
+
) AS sent_end,
|
|
998
|
+
(
|
|
999
|
+
SELECT count()
|
|
1000
|
+
FROM (
|
|
1001
|
+
SELECT finalized."requestId"
|
|
1002
|
+
FROM RedeemFinalized AS finalized
|
|
1003
|
+
INNER JOIN RedeemRequested AS requested
|
|
1004
|
+
ON requested.address = finalized.address
|
|
1005
|
+
AND requested."requestId" = finalized."requestId"
|
|
1006
|
+
WHERE finalized.address = '${options.vault}'
|
|
1007
|
+
AND requested.requester = '${options.account}'
|
|
1008
|
+
AND requested.block_num <= ${options.startBlockNumber}
|
|
1009
|
+
AND finalized.block_num > ${options.startBlockNumber}
|
|
1010
|
+
AND finalized.block_num <= ${options.blockNumber}
|
|
1011
|
+
UNION ALL
|
|
1012
|
+
SELECT cancelled."requestId"
|
|
1013
|
+
FROM RedeemCancelled AS cancelled
|
|
1014
|
+
INNER JOIN RedeemRequested AS requested
|
|
1015
|
+
ON requested.address = cancelled.address
|
|
1016
|
+
AND requested."requestId" = cancelled."requestId"
|
|
1017
|
+
WHERE cancelled.address = '${options.vault}'
|
|
1018
|
+
AND requested.requester = '${options.account}'
|
|
1019
|
+
AND requested.block_num <= ${options.startBlockNumber}
|
|
1020
|
+
AND cancelled.block_num > ${options.startBlockNumber}
|
|
1021
|
+
AND cancelled.block_num <= ${options.blockNumber}
|
|
1022
|
+
) AS cross_boundary
|
|
1023
|
+
) AS cross_boundary_redemptions
|
|
1024
|
+
`,
|
|
1025
|
+
signatures: [redeemCancelledSignature, redeemFinalizedSignature, redeemRequestedSignature],
|
|
1026
|
+
});
|
|
1027
|
+
const row = result.rows[0];
|
|
1028
|
+
const crossBoundaryRedemptions = Value.toNumber(row?.['cross_boundary_redemptions']);
|
|
1029
|
+
const receivedEnd = Value.toIntegerString(row?.['received_end']);
|
|
1030
|
+
const receivedStart = Value.toIntegerString(row?.['received_start']);
|
|
1031
|
+
const sentEnd = Value.toIntegerString(row?.['sent_end']);
|
|
1032
|
+
const sentStart = Value.toIntegerString(row?.['sent_start']);
|
|
1033
|
+
if (crossBoundaryRedemptions === undefined ||
|
|
1034
|
+
receivedEnd === undefined ||
|
|
1035
|
+
receivedStart === undefined ||
|
|
1036
|
+
sentEnd === undefined ||
|
|
1037
|
+
sentStart === undefined)
|
|
1038
|
+
return undefined;
|
|
1039
|
+
const receivedEndValue = BigInt(receivedEnd);
|
|
1040
|
+
const receivedStartValue = BigInt(receivedStart);
|
|
1041
|
+
const sentEndValue = BigInt(sentEnd);
|
|
1042
|
+
const sentStartValue = BigInt(sentStart);
|
|
1043
|
+
if (sentEndValue > receivedEndValue || sentStartValue > receivedStartValue)
|
|
1044
|
+
return undefined;
|
|
1045
|
+
return {
|
|
1046
|
+
crossBoundaryRedemption: crossBoundaryRedemptions > 0,
|
|
1047
|
+
endShares: receivedEndValue - sentEndValue,
|
|
1048
|
+
startShares: receivedStartValue - sentStartValue,
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
843
1051
|
/** Returns whether an account sent or received Earn shares outside known vault flows. */
|
|
844
1052
|
async function hasExternalShareTransfer(tidx, options) {
|
|
845
1053
|
// Vault exits pull shares into the vault before burning. Reconcile counts by transaction and amount so unmatched direct sends remain external.
|
|
@@ -851,10 +1059,15 @@ async function hasExternalShareTransfer(tidx, options) {
|
|
|
851
1059
|
SELECT count()
|
|
852
1060
|
FROM token_transfers
|
|
853
1061
|
WHERE token = '${options.shareToken.toLowerCase()}'
|
|
1062
|
+
AND block_num > ${options.startBlockNumber}
|
|
854
1063
|
AND block_num <= ${options.blockNumber}
|
|
855
1064
|
AND (
|
|
856
1065
|
("from" = '${options.account}' AND "to" != '${options.vault}')
|
|
857
|
-
OR (
|
|
1066
|
+
OR (
|
|
1067
|
+
"to" = '${options.account}'
|
|
1068
|
+
AND "from" != '${zeroAddress}'
|
|
1069
|
+
AND "from" != '${options.vault}'
|
|
1070
|
+
)
|
|
858
1071
|
)
|
|
859
1072
|
) + (
|
|
860
1073
|
SELECT count()
|
|
@@ -864,6 +1077,7 @@ async function hasExternalShareTransfer(tidx, options) {
|
|
|
864
1077
|
WHERE token = '${options.shareToken.toLowerCase()}'
|
|
865
1078
|
AND "from" = '${options.account}'
|
|
866
1079
|
AND "to" = '${options.vault}'
|
|
1080
|
+
AND block_num > ${options.startBlockNumber}
|
|
867
1081
|
AND block_num <= ${options.blockNumber}
|
|
868
1082
|
GROUP BY tx_hash, amount
|
|
869
1083
|
) AS candidate
|
|
@@ -874,27 +1088,58 @@ async function hasExternalShareTransfer(tidx, options) {
|
|
|
874
1088
|
FROM Redeemed
|
|
875
1089
|
WHERE address = '${options.vault}'
|
|
876
1090
|
AND caller = '${options.account}'
|
|
1091
|
+
AND block_num > ${options.startBlockNumber}
|
|
877
1092
|
AND block_num <= ${options.blockNumber}
|
|
878
1093
|
UNION ALL
|
|
879
1094
|
SELECT tx_hash, toUInt256(earnShares) AS amount
|
|
880
1095
|
FROM RedeemRequested
|
|
881
1096
|
WHERE address = '${options.vault}'
|
|
882
1097
|
AND requester = '${options.account}'
|
|
1098
|
+
AND block_num > ${options.startBlockNumber}
|
|
883
1099
|
AND block_num <= ${options.blockNumber}
|
|
884
1100
|
UNION ALL
|
|
885
1101
|
SELECT tx_hash, toUInt256(earnSharesBurned) AS amount
|
|
886
1102
|
FROM WithdrewExact
|
|
887
1103
|
WHERE address = '${options.vault}'
|
|
888
1104
|
AND caller = '${options.account}'
|
|
1105
|
+
AND block_num > ${options.startBlockNumber}
|
|
889
1106
|
AND block_num <= ${options.blockNumber}
|
|
890
1107
|
) AS protocol_exit
|
|
891
1108
|
GROUP BY tx_hash, amount
|
|
892
1109
|
) AS matched
|
|
893
1110
|
ON matched.tx_hash = candidate.tx_hash AND matched.amount = candidate.amount
|
|
894
1111
|
WHERE candidate.transfer_count > coalesce(matched.exit_count, 0)
|
|
1112
|
+
) + (
|
|
1113
|
+
SELECT count()
|
|
1114
|
+
FROM (
|
|
1115
|
+
SELECT tx_hash, toUInt256(amount) AS amount, count() AS transfer_count
|
|
1116
|
+
FROM token_transfers
|
|
1117
|
+
WHERE token = '${options.shareToken.toLowerCase()}'
|
|
1118
|
+
AND "from" = '${options.vault}'
|
|
1119
|
+
AND "to" = '${options.account}'
|
|
1120
|
+
AND block_num > ${options.startBlockNumber}
|
|
1121
|
+
AND block_num <= ${options.blockNumber}
|
|
1122
|
+
GROUP BY tx_hash, amount
|
|
1123
|
+
) AS candidate
|
|
1124
|
+
LEFT JOIN (
|
|
1125
|
+
SELECT tx_hash, toUInt256(earnShares) AS amount, count() AS cancel_count
|
|
1126
|
+
FROM RedeemCancelled
|
|
1127
|
+
WHERE address = '${options.vault}'
|
|
1128
|
+
AND receiver = '${options.account}'
|
|
1129
|
+
AND block_num > ${options.startBlockNumber}
|
|
1130
|
+
AND block_num <= ${options.blockNumber}
|
|
1131
|
+
GROUP BY tx_hash, amount
|
|
1132
|
+
) AS matched
|
|
1133
|
+
ON matched.tx_hash = candidate.tx_hash AND matched.amount = candidate.amount
|
|
1134
|
+
WHERE candidate.transfer_count > coalesce(matched.cancel_count, 0)
|
|
895
1135
|
) AS count
|
|
896
1136
|
`,
|
|
897
|
-
signatures: [
|
|
1137
|
+
signatures: [
|
|
1138
|
+
redeemCancelledSignature,
|
|
1139
|
+
redeemedSignature,
|
|
1140
|
+
redeemRequestedSignature,
|
|
1141
|
+
withdrewExactSignature,
|
|
1142
|
+
],
|
|
898
1143
|
});
|
|
899
1144
|
const count = Value.toNumber(result.rows[0]?.['count']);
|
|
900
1145
|
if (count === undefined)
|