Skip to content
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
79 changes: 68 additions & 11 deletions .github/workflows/audit_agent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,71 @@ jobs:
- name: Quick Scan
if: steps.extract.outputs.should_scan == 'true'
run: |
curl -X POST \
-H "Content-Type: application/json" \
-H "X-Api-Key: $AUDIT_AGENT_TOKEN" \
-d '{
"githubUrl": "${{ github.event.repository.html_url }}",
"branchName": "${{ github.event.pull_request.head.ref }}",
"issueNumber": ${{ github.event.number }},
"commitHash": "${{ github.event.pull_request.head.sha }}",
"contractFiles": ${{ steps.extract.outputs.files }}
}' \
https://api.auditagent.nethermind.io/api/v1/scanner/quick-scan/launch
set -e
API_URL="https://api.auditagent.nethermind.io"
HTTP_CODE=$(curl -s -w "%{http_code}" -o launch_response.json -X POST -H "Content-Type: application/json" -H "X-Api-Key: $AUDIT_AGENT_TOKEN" -d '{
"githubUrl": "${{ github.event.repository.html_url }}",
"baseBranchName": "${{ github.event.pull_request.base.ref }}",
"branchName": "${{ github.event.pull_request.head.ref }}",
"issueNumber": ${{ github.event.number }},
"baseCommitHash": "${{ github.event.pull_request.base.sha }}",
"commitHash": "${{ github.event.pull_request.head.sha }}",
"contractFiles": ${{ steps.extract.outputs.files }},
"language": "solidity"
}' "$API_URL/api/v1/scanner/quick-scan/diff-scan")
if [ "$HTTP_CODE" != "202" ]; then
echo "Launch failed. Expected 202, got $HTTP_CODE."
cat launch_response.json
exit 1
fi
SCAN_ID=$(cat launch_response.json | tr -d '\000-\037' | jq -r '.data.scan_id // empty')
if [ -z "$SCAN_ID" ]; then
echo "No relevant changes found. No scan needed."
exit 0
fi
echo "Scan started: $SCAN_ID"
while true; do
RESULT_JSON=$(curl -s -f -H "X-Api-Key: $AUDIT_AGENT_TOKEN" "$API_URL/api/v1/scans/ci-result/$SCAN_ID")
STATUS=$(echo "$RESULT_JSON" | tr -d '\000-\037' | jq -r '.data.scan.status // empty')
if [ "$STATUS" = "completed" ]; then
echo "Scan completed successfully."
exit 0
fi
if [ "$STATUS" = "failed" ]; then
echo "Scan failed."
exit 1
fi
echo "Scan status: $STATUS (waiting...)"
sleep 60
done
merge-context:
if: ${{ github.event.action == 'closed' && github.event.pull_request.merged == true }}
runs-on: ubuntu-latest
env:
AUDIT_AGENT_TOKEN: ${{ secrets.AUDIT_AGENT_TOKEN }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch latest target branch and get new commit hash
id: merged_commit
run: |
git fetch origin main:origin/main
NEW_COMMIT_HASH=$(git rev-parse origin/main)
echo "hash=$NEW_COMMIT_HASH" >> $GITHUB_OUTPUT
- name: Merge Context
run: |
RESPONSE=$(curl -s -w "%{http_code}" -o response.json -X POST -H "Content-Type: application/json" -H "X-Api-Key: $AUDIT_AGENT_TOKEN" -d '{
"githubUrl": "${{ github.event.repository.html_url }}",
"baseBranchName": "${{ github.event.pull_request.base.ref }}",
"baseCommitHash": "${{ steps.merged_commit.outputs.hash }}",
"branchName": "${{ github.event.pull_request.head.ref }}",
"issueNumber": ${{ github.event.number }},
"commitHash": "${{ github.event.pull_request.head.sha }}"
}' https://api.auditagent.nethermind.io/api/v1/scanner/quick-scan/merge)
STATUS_CODE="${RESPONSE: -3}"
if [ "$STATUS_CODE" != "202" ]; then
echo "API call failed. Expected 202, got $STATUS_CODE."
cat response.json
exit 1
fi
13 changes: 8 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ on:
workflow_dispatch:

env:
ETH_NODE_URL: ${{ secrets.ETH_NODE_URL }}
BSC_NODE_URL: ${{ secrets.BSC_NODE_URL }}
SEPOLIA_NODE_URL: ${{ secrets.SEPOLIA_NODE_URL }}
OP_NODE_URL: ${{ secrets.OP_NODE_URL }}
RPC_1: ${{ secrets.RPC_1 }}
RPC_56: ${{ secrets.RPC_56 }}
RPC_11155111: ${{ secrets.RPC_11155111 }}
RPC_10: ${{ secrets.RPC_10 }}

jobs:
test:
Expand All @@ -37,11 +37,14 @@ jobs:
- name: Run tests
run: forge test --nmt "testMockActionExecuteSuccessP256|testMockActionExecuteSuccessWebAuthn"
id: test
if: always()

- name: Run tests P256
run: forge test --mt testMockActionExecuteSuccessP256 --evm-version osaka
id: test-p256
if: always()

- name: Run tests WebAuthn
run: forge test --mt testMockActionExecuteSuccessWebAuthn --evm-version osaka
id: test-webauthn
id: test-webauthn
if: always()
6 changes: 4 additions & 2 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ sort_imports = true
runs = 20

[rpc_endpoints]
mainnet = "${ETH_NODE_URL}"
bsc_mainnet = "${BSC_NODE_URL}"
mainnet = "${RPC_1}"
bsc_mainnet = "${RPC_56}"
sepolia = "${RPC_11155111}"
optimism_mainnet = "${RPC_10}"

[etherscan]
mainnet = { key = "${ETHERSCAN_API_KEY}" }
40 changes: 34 additions & 6 deletions src/KSSmartIntentRouterAccounting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ abstract contract KSSmartIntentRouterAccounting is
using PermitHelper for address;

mapping(bytes32 => mapping(address => uint256)) public erc20Allowances;
uint256 internal constant ERC721_WILDCARD_TOKEN_ID = type(uint256).max;
uint256 internal constant ERC721_IDS_SEPARATOR = type(uint256).max;

/// @notice Set the tokens' allowances for the intent
function _approveTokens(bytes32 intentHash, TokenData calldata tokenData, address mainAddress)
Expand Down Expand Up @@ -79,13 +81,39 @@ abstract contract KSSmartIntentRouterAccounting is
}
approvalFlags >>= actionData.erc20Ids.length;

for (uint256 i = 0; i < actionData.erc721Ids.length; i++) {
address token = tokenData.erc721Data[actionData.erc721Ids[i]].token;
uint256 tokenId = tokenData.erc721Data[actionData.erc721Ids[i]].tokenId;
uint256 wildcardSeprator = _parseWildcardSeprator(actionData.erc721Ids);
uint256 wildcardCursor = wildcardSeprator + 1;

for (uint256 i = 0; i < wildcardSeprator; i++) {
ERC721Data calldata erc721Data = tokenData.erc721Data[actionData.erc721Ids[i]];
address token = erc721Data.token;
bool approvalFlag = _checkFlag(approvalFlags, i);

if (erc721Data.tokenId != ERC721_WILDCARD_TOKEN_ID) {
ERC721DataLibrary.collect(
token, erc721Data.tokenId, mainAddress, actionContract, _forwarder, approvalFlag
);
} else {
ERC721DataLibrary.collect(
token,
actionData.erc721Ids[wildcardCursor++],
mainAddress,
actionContract,
_forwarder,
approvalFlag
);
}
}
}

ERC721DataLibrary.collect(
token, tokenId, mainAddress, actionContract, _forwarder, _checkFlag(approvalFlags, i)
);
function _parseWildcardSeprator(uint256[] calldata erc721Ids)
internal
pure
returns (uint256 wildcardSeprator)
{
wildcardSeprator = erc721Ids.length;
for (uint256 i = 0; i < erc721Ids.length; i++) {
if (erc721Ids[i] == ERC721_IDS_SEPARATOR) return i;
}
}

Expand Down
Loading
Loading