Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decode this as a swap with the heuristic #380

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/contextualizers/heuristics/erc20Swap/erc20Swap.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import erc20Swap0xd55dc9b2 from '../../test/transactions/erc20Swap-0xd55dc9b2.js
import erc20Swap0x6ef80cce from '../../test/transactions/erc20Swap-0x6ef80cce.json';
import erc20swap0x2c631258 from '../../test/transactions/erc20swap-0x2c631258.json';
import erc20Swap0x96f5e3fb from '../../test/transactions/erc20Swap-0x96f5e3fb.json';
import erc20Swap0x4d127476 from '../../test/transactions/erc20Swap-0x4d127476.json';
import catchall0xc35c01ac from '../../test/transactions/catchall-0xc35c01ac.json';

describe('ERC20 Swap', () => {
Expand All @@ -25,6 +26,9 @@ describe('ERC20 Swap', () => {

const isERC20Swap4 = detect(erc20Swap0x96f5e3fb as unknown as Transaction);
expect(isERC20Swap4).toBe(true);

const isERC20Swap5 = detect(erc20Swap0x4d127476 as unknown as Transaction);
expect(isERC20Swap5).toBe(true);
});

it('Should generate context', () => {
Expand Down Expand Up @@ -57,6 +61,12 @@ describe('ERC20 Swap', () => {
expect(desc4).toBe(
'0x605e05bf092ebd18e06d1b0f699df5b9dd85d452 SWAPPED 20398910132192029774490 0xeb1c32ea4e392346795aed3607f37646e2a9c13f for 2748.521373404267795478 ETH',
);

const generated5 = generate(erc20Swap0x4d127476 as unknown as Transaction);
const desc5 = contextSummary(generated5.context);
expect(desc5).toBe(
'0x5507dbd48a5a5bace8a6030e878cc4e0af147c33 SWAPPED 0.029472790148424173 ETH for 600000000000000000000000 0xa6b280b42cb0b7c4a4f789ec6ccc3a7609a1bc39',
);
});

it('Should not detect as ERC20 Swap transaction', () => {
Expand Down
25 changes: 15 additions & 10 deletions src/contextualizers/heuristics/erc20Swap/erc20Swap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ export function detect(transaction: Transaction): boolean {
// From account (swapper) sent and received 1 asset
if (
!(
transaction.netAssetTransfers?.[transaction.from]?.received?.length ===
1 &&
transaction.netAssetTransfers?.[transaction.from]?.sent?.length === 1
transaction.netAssetTransfers?.[transaction.from]?.sent?.length === 1 &&
transaction.netAssetTransfers?.[transaction.from]?.received?.length >= 1
)
) {
return false;
Expand All @@ -59,12 +58,13 @@ export function detect(transaction: Transaction): boolean {
const swapperSent = transaction.netAssetTransfers[transaction.from]
.sent[0] as ERC20Asset;
const swapperReceived = transaction.netAssetTransfers[transaction.from]
.received[0] as ERC20Asset;
.received as ERC20Asset[];

// Swapper did not send and receive the same type of asset
if (
swapperSent.type === swapperReceived.type &&
swapperSent.contract === swapperReceived.contract
swapperReceived.filter((asset) => asset.type === swapperSent.type).length &&
swapperReceived.filter((asset) => asset.contract === swapperSent.contract)
.length
) {
return false;
}
Expand Down Expand Up @@ -97,15 +97,20 @@ export function generate(transaction: Transaction): Transaction {
...assetSent[0],
unit: 'wei',
} as ContextETHType);

// Find the asset received with the most amount
const assetSwappedTo = assetReceived.reduce((max, item) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open question: Whether to show both tokens here for the heuristic

return item.value > max.value ? item : max;
}, assetReceived[0]);
// Net asset transfers calls the token contract 'asset' instead of 'token'
const swapTo =
assetReceived[0].type === AssetType.ERC20
assetSwappedTo.type === AssetType.ERC20
? ({
...assetReceived[0],
token: assetReceived[0]?.contract,
...assetSwappedTo,
token: assetSwappedTo?.contract,
} as ContextERC20Type)
: ({
...assetReceived[0],
...assetSwappedTo,
unit: 'wei',
} as ContextETHType);
// Net asset transfers calls the token contract 'asset' instead of 'token'
Expand Down
Loading
Loading