Skip to content
2 changes: 1 addition & 1 deletion src/components/ppom/batching.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export function ppomMaliciousBatchingAndQueueing(parentContainer) {
params: [
{
from: globalContext.accounts[0],
to: '0x5FbDB2315678afecb367f032d93F642f64180aa3',

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

remove hardcoded malicious address, and use the const

to: maliciousAddress,
value: '0x0',
gasLimit: MIN_GAS_LIMIT,
maxFeePerGas: '0x2540be400',
Expand Down
220 changes: 220 additions & 0 deletions src/components/ppom/eip5792.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
import globalContext from '../..';
import { DEFAULT_CALLS, VERSION } from '../transactions/eip5792/sendCalls';
import { getMaliciousTransactions } from './sharedConstants';

export function ppomMaliciousSendCalls(parentContainer) {
parentContainer.insertAdjacentHTML(
'beforeend',
`<div class="col-xl-4 col-lg-6 col-md-12 col-sm-12 col-12 d-flex align-items-stretch">
<div class="card full-width">
<div class="card-body">
<h4 class="card-title">
PPOM - EIP 5792 - Malicious Send Calls
</h4>
<button class="btn btn-primary btn-lg btn-block mb-3" id="ppomSendMaliciousEthButton">
Send Calls with Malicious ETH Transfer
</button>
<button class="btn btn-primary btn-lg btn-block mb-3" id="ppomSendMaliciousERC20TransferButton">
Send Calls with Malicious ERC20 Transfer (USDC)
</button>
<button class="btn btn-primary btn-lg btn-block mb-3" id="ppomSendMaliciousERC20ApprovalButton">
Send Calls with Malicious ERC20 Approval (BUSDC)
</button>
<button class="btn btn-primary btn-lg btn-block mb-3" id="ppomSendMaliciousSetApprovalForAllButton">
Send Calls with Malicious Set Approval for All
</button>
<button class="btn btn-primary btn-lg btn-block mb-3" id="ppomSendMaliciousContractInteractionButton">
Send Calls with Malicious Contract Interaction
</button>
<button class="btn btn-primary btn-lg btn-block mb-3" id="ppomSendThreeMaliciousTxsButton">
Send Calls with 3 Malicious Transactions
</button>
<hr/>
<div id="ppomRequestIdContainer" hidden>
<label>Request ID:</label>
<input type="text" id="ppomRequestIdInput" class="form-control" readonly />
</div>
<p class="info-text alert alert-warning" id="ppomSendCallsErrorContainer" hidden>
<span class="wrap" id="ppomSendCallsError"></span>
</p>
<button class="btn btn-primary btn-lg btn-block mb-3" id="ppomGetCallsStatusButton" disabled>
Get Calls Status
</button>
<p class="info-text alert alert-success">
<span class="wrap" id="ppomGetCallsStatusResult">Status</span>
</p>
</div>
</div>
</div>`,
);

const ppomSendMaliciousEthButton = document.getElementById(
'ppomSendMaliciousEthButton',
);

ppomSendMaliciousEthButton.onclick = async () => {
await sendMaliciousCalls('eth');
};

const ppomSendMaliciousERC20TransferButton = document.getElementById(
'ppomSendMaliciousERC20TransferButton',
);

ppomSendMaliciousERC20TransferButton.onclick = async () => {
await sendMaliciousCalls('erc20Transfer');
};

const ppomSendMaliciousERC20ApprovalButton = document.getElementById(
'ppomSendMaliciousERC20ApprovalButton',
);

ppomSendMaliciousERC20ApprovalButton.onclick = async () => {
await sendMaliciousCalls('erc20Approval');
};

const ppomSendMaliciousSetApprovalForAllButton = document.getElementById(
'ppomSendMaliciousSetApprovalForAllButton',
);

ppomSendMaliciousSetApprovalForAllButton.onclick = async () => {
await sendMaliciousCalls('setApprovalForAll');
};

const ppomSendMaliciousContractInteractionButton = document.getElementById(
'ppomSendMaliciousContractInteractionButton',
);

ppomSendMaliciousContractInteractionButton.onclick = async () => {
await sendMaliciousCalls('maliciousContractInteraction');
};

const ppomSendThreeMaliciousTxsButton = document.getElementById(
'ppomSendThreeMaliciousTxsButton',
);

ppomSendThreeMaliciousTxsButton.onclick = async () => {
await sendThreeMaliciousCalls();
};

document.addEventListener('globalConnectionChange', function (e) {
if (e.detail.connected) {
// MetaMask is connected, enable the button
ppomSendMaliciousEthButton.disabled = false;
ppomSendMaliciousERC20TransferButton.disabled = false;
ppomSendMaliciousERC20ApprovalButton.disabled = false;
ppomSendMaliciousSetApprovalForAllButton.disabled = false;
ppomSendMaliciousContractInteractionButton.disabled = false;
ppomSendThreeMaliciousTxsButton.disabled = false;
}
});

document.addEventListener('disableAndClear', function () {
ppomSendMaliciousEthButton.disabled = true;
ppomSendMaliciousERC20TransferButton.disabled = true;
ppomSendMaliciousERC20ApprovalButton.disabled = true;
ppomSendMaliciousSetApprovalForAllButton.disabled = true;
ppomSendMaliciousContractInteractionButton.disabled = true;
ppomSendThreeMaliciousTxsButton.disabled = true;
});

async function sendMaliciousCalls(type) {
const maliciousTransactions = getMaliciousTransactions(globalContext);
const calls = [];

switch (type) {
case 'eth':
calls.push(maliciousTransactions.eth);
break;
case 'erc20Transfer':
calls.push(maliciousTransactions.erc20Transfer);
break;
case 'erc20Approval':
calls.push(maliciousTransactions.erc20Approval);
break;
case 'maliciousContractInteraction':
calls.push(maliciousTransactions.maliciousContractInteraction);
break;
case 'setApprovalForAll':
calls.push(maliciousTransactions.setApprovalForAll);
break;
default:
// Do nothing
break;
}

calls.push(...DEFAULT_CALLS);

try {
const result = await globalContext.provider.request({
method: 'wallet_sendCalls',
params: [getParams(calls)],
});
document.getElementById('ppomRequestIdInput').value = result.id;
document.getElementById('ppomRequestIdContainer').hidden = false;
document.getElementById('ppomGetCallsStatusButton').disabled = false;
document.getElementById('ppomSendCallsErrorContainer').hidden = true;
} catch (error) {
console.error(error);
document.getElementById('ppomSendCallsErrorContainer').hidden = false;
document.getElementById(
'ppomSendCallsError',
).innerHTML = `Error: ${error.message}`;
}
}

async function sendThreeMaliciousCalls() {
const maliciousTransactions = getMaliciousTransactions(globalContext);

const calls = [
maliciousTransactions.erc20Approval,
maliciousTransactions.setApprovalForAll,
maliciousTransactions.maliciousContractInteraction,
];

try {
const result = await globalContext.provider.request({
method: 'wallet_sendCalls',
params: [getParams(calls)],
});
document.getElementById('ppomRequestIdInput').value = result.id;
document.getElementById('ppomRequestIdContainer').hidden = false;
document.getElementById('ppomGetCallsStatusButton').disabled = false;
document.getElementById('ppomSendCallsErrorContainer').hidden = true;
} catch (error) {
console.error(error);
document.getElementById('ppomSendCallsErrorContainer').hidden = false;
document.getElementById(
'ppomSendCallsError',
).innerHTML = `Error: ${error.message}`;
}
}

// Get Calls Status functionality
document.getElementById('ppomGetCallsStatusButton').onclick = async () => {
const requestId = document.getElementById('ppomRequestIdInput').value;
const resultOutput = document.getElementById('ppomGetCallsStatusResult');

try {
const result = await globalContext.provider.request({
method: 'wallet_getCallsStatus',
params: [requestId],
});

resultOutput.innerHTML = JSON.stringify(result, null, 2);
document.getElementById('ppomGetCallsStatusButton').disabled = false;
} catch (error) {
console.error(error);
resultOutput.innerHTML = `Error: ${error.message}`;
}
};

function getParams(calls) {
return {
version: VERSION,
from: globalContext.accounts[0],
chainId: `0x${globalContext.chainIdInt.toString(16)}`,
atomicRequired: true,
calls,
};
}
}
3 changes: 2 additions & 1 deletion src/components/ppom/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './transactions';
export * from './batching';
export * from './bypasses';
export * from './eip5792';
export * from './transactions';
51 changes: 51 additions & 0 deletions src/components/ppom/sharedConstants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { maliciousAddress } from '../../sample-addresses';

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

moved the malicious tx's in this file, so they can be used both in the ppom tx and in the ppom batch txs

import {
ERC20_SAMPLE_CONTRACTS,
ERC721_SAMPLE_CONTRACTS,
MALICIOUS_CONTRACT_ADDRESSES,
NETWORKS_BY_CHAIN_ID,
} from '../../onchain-sample-contracts';

const maliciousTransactionsCache = {};

export const getMaliciousTransactions = (globalContext) => {
const chainId = globalContext.chainIdInt;
const networkName = NETWORKS_BY_CHAIN_ID[chainId] || 'default';

// to avoid recalculating the tx object everytime if the chainId hasn't changed
if (maliciousTransactionsCache[chainId]) {
return maliciousTransactionsCache[chainId];
}

const transactions = {
eth: {
to: maliciousAddress,
value: '0x9184e72a000',
},
erc20Transfer: {
to: ERC20_SAMPLE_CONTRACTS[networkName],
data: '0xa9059cbb0000000000000000000000005fbdb2315678afecb367f032d93f642f64180aa30000000000000000000000000000000000000000000000000000000000000064',
value: '0x0',
},
erc20Approval: {
to: ERC20_SAMPLE_CONTRACTS[networkName],
data: '0x095ea7b3000000000000000000000000e50a2dbc466d01a34c3e8b7e8e45fce4f7da39e6000000000000000000000000000000000000000000000000ffffffffffffffff',
value: '0x0',
},
setApprovalForAll: {
to: ERC721_SAMPLE_CONTRACTS[networkName],
data: '0xa22cb465000000000000000000000000b85492afc686d5ca405e3cd4f50b05d358c75ede0000000000000000000000000000000000000000000000000000000000000001',
value: '0x0',
},
maliciousContractInteraction: {
to:
MALICIOUS_CONTRACT_ADDRESSES[networkName] ||
MALICIOUS_CONTRACT_ADDRESSES.default,
data: '0xef5cfb8c0000000000000000000000000b3e87a076ac4b0d1975f0f232444af6deb96c59',
value: '0x0',
},
};

maliciousTransactionsCache[chainId] = transactions;
return transactions;
};
Comment thread
digiwand marked this conversation as resolved.
Loading