Stellar iOS Mac SDK
Soneso/stellar-ios-mac-sdk
Guides Stellar blockchain development in Swift using stellar-ios-mac-sdk.
Detects unsafe external call patterns and token integration vulnerabilities in smart contracts.
$ npx skills add quillai-network/quillshield_skills --skill external-call-safety -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install quillai-network/quillshield_skills external-call-safety --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/quillai-network/quillshield_skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/external-call-safety/skills/external-call-safety .claude/skills/external-call-safety && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "external-call-safety" agent skill from https://github.com/quillai-network/quillshield_skills/tree/main/plugins/external-call-safety/skills/external-call-safety into .claude/skills/external-call-safety/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "external-call-safety", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/quillai-network/quillshield_skills/tree/main/plugins/external-call-safety/skills/external-call-safetyType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add quillai-network/quillshield_skills --skill external-call-safety -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install quillai-network/quillshield_skills external-call-safety --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quillai-network/quillshield_skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/plugins/external-call-safety/skills/external-call-safety .agents/skills/external-call-safety && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "external-call-safety" agent skill from https://github.com/quillai-network/quillshield_skills/tree/main/plugins/external-call-safety/skills/external-call-safety into .agents/skills/external-call-safety/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "external-call-safety", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add quillai-network/quillshield_skills --skill external-call-safety -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install quillai-network/quillshield_skills external-call-safety --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quillai-network/quillshield_skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/plugins/external-call-safety/skills/external-call-safety .cursor/skills/external-call-safety && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "external-call-safety" agent skill from https://github.com/quillai-network/quillshield_skills/tree/main/plugins/external-call-safety/skills/external-call-safety into .cursor/skills/external-call-safety/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "external-call-safety", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/quillai-network/quillshield_skills.git --path plugins/external-call-safety/skills/external-call-safety--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add quillai-network/quillshield_skills --skill external-call-safety -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install quillai-network/quillshield_skills external-call-safety --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quillai-network/quillshield_skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/plugins/external-call-safety/skills/external-call-safety .gemini/skills/external-call-safety && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "external-call-safety" agent skill from https://github.com/quillai-network/quillshield_skills/tree/main/plugins/external-call-safety/skills/external-call-safety into .gemini/skills/external-call-safety/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "external-call-safety", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install quillai-network/quillshield_skills external-call-safetyInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add quillai-network/quillshield_skills --skill external-call-safety -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/quillai-network/quillshield_skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/plugins/external-call-safety/skills/external-call-safety .github/skills/external-call-safety && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "external-call-safety" agent skill from https://github.com/quillai-network/quillshield_skills/tree/main/plugins/external-call-safety/skills/external-call-safety into .github/skills/external-call-safety/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "external-call-safety", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add quillai-network/quillshield_skills --skill external-call-safety -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install quillai-network/quillshield_skills external-call-safety --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quillai-network/quillshield_skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/plugins/external-call-safety/skills/external-call-safety .opencode/skills/external-call-safety && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "external-call-safety" agent skill from https://github.com/quillai-network/quillshield_skills/tree/main/plugins/external-call-safety/skills/external-call-safety into .opencode/skills/external-call-safety/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "external-call-safety", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
external-call-safetyDetects unsafe external call patterns and token integration vulnerabilities in smart contracts.
External Call Safety is an agent skill from quillai-network/quillshield_skills. Detects unsafe external call patterns and token integration vulnerabilities in smart contracts. Covers unchecked call/delegatecall/staticcall return values, fee-on-transfer tokens, rebasing tokens, tokens with missing return values (USDT), ERC-777 callback risks, unsafe approve race conditions, return data bombs, gas stipend limitations, and push vs pull payment patterns. Use when auditing contracts that interact with external contracts, integrate arbitrary ERC20 tokens, distribute payments, or make low-level…
Its SKILL.md is about 3.1k tokens, which your agent loads only when the skill is triggered. The skill folder holds 3 other files, including reference files (for example `references/call-safety-patterns.md` and `references/weird-erc20.md`).
It sits in Backend & APIs, covering Smart contracts, Async programming and Smart contract auditing. It works with Ethereum. The repository describes itself as: Structured skills for smart contract security audits. Infers state invariants, detects semantic guard gaps, models flash loan + oracle attack chains, simulates adversarial… The licence is MIT.
Read from SKILL.md and the folder at commit 8bdd3c0. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are solidity and markdown).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
External Call Safety loads about 3.1k tokens when it runs, and up to ~6.5k if it reads all its reference files. Until then it costs about 136 tokens; SKILL.md has 585 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from quillai-network/quillshield_skills at commit 8bdd3c0, republished under its MIT licence (© quillai-network). 585 words, ~3,071 tokens.
.claude/skills/external-call-safety/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.Detect vulnerabilities arising from unsafe interactions with external contracts and non-standard token behaviors that break protocol assumptions. Covers OWASP SC06 (Unchecked External Calls) plus the entire "weird ERC20" problem space.
call, delegatecall, staticcall)Low-level calls (call, delegatecall, staticcall) return a boolean indicating success. If unchecked, failed calls are silently ignored.
// VULNERABLE: Return value not checked
function withdraw(uint256 amount) external {
balances[msg.sender] -= amount;
payable(msg.sender).call{value: amount}(""); // Can fail silently!
// User's balance decreased but ETH not sent
}
// SAFE: Check return value
function withdraw(uint256 amount) external {
balances[msg.sender] -= amount;
(bool success, ) = payable(msg.sender).call{value: amount}("");
require(success, "Transfer failed");
}Detection Algorithm:
For each low-level call expression:
1. Is the return value captured? (bool success, bytes memory data) = ...
2. Is the success boolean checked? require(success) or if(!success) revert
3. If not captured or not checked → UNCHECKED RETURN VALUE
Severity:
- ETH transfer unchecked → CRITICAL (funds lost)
- Token operation unchecked → HIGH (state desync)
- Non-financial call unchecked → MEDIUM// DANGEROUS: transfer() and send() forward only 2300 gas
payable(recipient).transfer(amount); // Reverts if recipient needs > 2300 gas
payable(recipient).send(amount); // Returns false, often unchecked
// SAFE: Use call() with gas
(bool success, ) = payable(recipient).call{value: amount}("");
require(success, "Transfer failed");Why 2300 gas is dangerous:
receive() or fallback() that do more than emit an event will failSLOAD gas cost, breaking some existing contractsA malicious contract can return extremely large data to consume the caller's gas.
// Vulnerable to return data bomb
(bool success, bytes memory data) = untrustedContract.call(calldata);
// If untrustedContract returns 1MB of data, copying it costs massive gas
// SAFE: Limit return data or ignore it
(bool success, ) = untrustedContract.call(calldata); // Ignore return data
// Or use assembly to limit return data size// CRITICAL: delegatecall executes untrusted code in OUR storage context
function execute(address target, bytes calldata data) external {
target.delegatecall(data); // Untrusted code can overwrite ANY storage
}
// delegatecall should ONLY be used with trusted, immutable targetsSome tokens deduct a fee during transfer() and transferFrom(). The recipient receives less than the specified amount.
// VULNERABLE: Assumes received amount equals input amount
function deposit(uint256 amount) external {
token.transferFrom(msg.sender, address(this), amount);
balances[msg.sender] += amount; // Credits MORE than actually received!
}
// SAFE: Check actual balance change
function deposit(uint256 amount) external {
uint256 balanceBefore = token.balanceOf(address(this));
token.transferFrom(msg.sender, address(this), amount);
uint256 balanceAfter = token.balanceOf(address(this));
uint256 actualReceived = balanceAfter - balanceBefore;
balances[msg.sender] += actualReceived; // Credits actual amount
}Known fee-on-transfer tokens: STA, PAXG, USDT (fee currently 0 but can be activated), RFI/SAFEMOON forks.
Rebasing tokens change all balances proportionally without transfers. Protocol's accounting desynchronizes from actual balances.
// VULNERABLE: Stores absolute balance amounts
function deposit(uint256 amount) external {
token.transferFrom(msg.sender, address(this), amount);
userDeposit[msg.sender] = amount; // After rebase, actual balance differs!
}
// Mitigation options:
// 1. Store shares instead of amounts
// 2. Wrap rebasing token (wstETH pattern)
// 3. Explicitly state: "rebasing tokens not supported"Known rebasing tokens: stETH, AMPL, OHM, YAM, BASED.
Some tokens don't return a boolean from transfer()/transferFrom()/approve(), breaking the ERC20 standard.
// VULNERABLE: Assumes return value exists
bool success = token.transfer(recipient, amount); // Reverts if token returns nothing
// SAFE: Use SafeERC20
using SafeERC20 for IERC20;
token.safeTransfer(recipient, amount); // Handles missing return valuesKnown tokens with missing returns: USDT, BNB, OMG, KNC (legacy versions).
ERC-777 tokens trigger tokensToSend() on the sender and tokensReceived() on the recipient during transfers, enabling reentrancy.
ERC-777 callback hooks:
transfer() → calls tokensReceived() on recipient
transferFrom() → calls tokensToSend() on sender, tokensReceived() on recipient
send() → calls tokensToSend() on sender, tokensReceived() on recipient
ANY of these can re-enter the calling contract!Cross-reference: See reentrancy-pattern-analysis for detailed ERC-777 reentrancy detection.
// VULNERABLE: Approve race condition
token.approve(spender, newAmount);
// Between the approval TX and the spending TX, the spender can:
// 1. Spend the OLD allowance
// 2. Then spend the NEW allowance
// Total spent: oldAmount + newAmount (double spending)
// SAFE: Reset to zero first, or use increaseAllowance
token.approve(spender, 0); // Reset
token.approve(spender, newAmount); // Set new
// Or use SafeERC20
token.safeIncreaseAllowance(spender, amount);
// ALSO DANGEROUS: Some tokens (USDT) revert on non-zero to non-zero approve
token.approve(spender, newAmount); // REVERTS if current allowance != 0
// MUST reset to 0 first for USDTSome tokens can blacklist addresses, causing transfers to/from those addresses to revert.
// VULNERABLE: Assumes transfer always succeeds for valid amounts
function distribute(address[] calldata users, uint256[] calldata amounts) external {
for (uint i = 0; i < users.length; i++) {
token.transfer(users[i], amounts[i]); // Reverts if ANY user is blacklisted
// Entire batch fails!
}
}
// SAFE: Handle per-user failures
function distribute(address[] calldata users, uint256[] calldata amounts) external {
for (uint i = 0; i < users.length; i++) {
try IERC20(token).transfer(users[i], amounts[i]) {
// Success
} catch {
// Log failure, skip this user, don't block others
}
}
}Known blacklist tokens: USDC, USDT, TUSD.
Some tokens have maximum transfer amounts per transaction or maximum holding amounts per address.
// Protocol may assume any amount can be transferred
// But some tokens: require(amount <= maxTransferAmount)
// This can brick protocols that batch large transfersPUSH (Dangerous):
Contract sends funds TO recipients
- Can fail if recipient is a contract that reverts
- Can be DoS'd by one malicious recipient
- Gas costs unpredictable
PULL (Safe):
Recipients claim funds FROM contract
- Each claim is independent
- One user's failure doesn't affect others
- Gas costs predictable per claimDetection:
For each function that sends ETH or tokens to external addresses:
If sending to user-supplied addresses in a loop → PUSH pattern
If sending to individual addresses via claim function → PULL pattern
PUSH pattern with untrusted recipients → HIGH risk of DoSTask Progress:
- [ ] Step 1: Find all external calls (call, delegatecall, staticcall, transfer, send)
- [ ] Step 2: Verify return values are checked for all external calls
- [ ] Step 3: Identify all token interactions and classify token assumptions
- [ ] Step 4: Check for fee-on-transfer compatibility (balance before/after pattern)
- [ ] Step 5: Check for rebasing token compatibility
- [ ] Step 6: Verify SafeERC20 usage for tokens with missing return values
- [ ] Step 7: Check approve patterns for race conditions and USDT compatibility
- [ ] Step 8: Analyze payment distribution pattern (push vs pull)
- [ ] Step 9: Score findings and generate report## External Call Safety Report
### Finding: [Title]
**Function:** `functionName()` at `Contract.sol:L42`
**Category:** [Unchecked Return | Fee-on-Transfer | Rebasing | Missing Return | Callback | Approve Race | DoS]
**Severity:** [CRITICAL | HIGH | MEDIUM]
**Issue:**
[Description of the unsafe external call or token integration issue]
**Affected Tokens:**
[List of known tokens that trigger this issue, e.g., USDT, USDC, stETH]
**Vulnerable Code:**
[Code snippet]
**Attack Scenario:**
1. [Step-by-step exploitation]
**Recommendation:**
[Use SafeERC20, balance-before-after, pull pattern, etc.]call return values checked (require(success))?SafeERC20 for all token interactions?approve() reset to 0 before setting new allowance (USDT compatibility)?delegatecall only used with trusted, immutable targets?For weird ERC20 catalog, see {baseDir}/references/weird-erc20.md. For call safety patterns, see {baseDir}/references/call-safety-patterns.md.
© quillai-network, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 2 other files (references) in plugins/external-call-safety/skills/external-call-safety of quillai-network/quillshield_skills.
Open the folder on GitHubat commit 8bdd3c0
External Call Safety next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| External Call Safety this skillquillai-network/quillshield_skills | 130 | — | ~3.1k | Automated safety check: Pass | MIT | |
| Stellar iOS Mac SDKSoneso/stellar-ios-mac-sdk | 132 | — | ~4.3k | Automated safety check: Pass | Apache-2.0 | |
| Smart Contract Auditforefy/.context | 152 | 1 repos | ~5.1k | Automated safety check: Pass | MIT | |
| Fizz Convertpashov/skills | 1.2k | 2 repos | ~3.7k | Automated safety check: Pass | MIT | |
| Smart Contract Auditgreatpie/smart-contract-audit-skill | 101 | — | ~1.1k | Automated safety check: Pass | None | |
| Solidity AuditorGabson0x/bountyforge | 442 | — | ~3.7k | Automated safety check: Pass | None |
Soneso/stellar-ios-mac-sdk
Guides Stellar blockchain development in Swift using stellar-ios-mac-sdk.
forefy/.context
Comprehensive smart contract security audit framework with multi-expert analysis.
pashov/skills
Convert English-language properties in PROPERTIES.md (produced by the Fizz skill) into Solidity assertions inside the existing fuzz harness, then flip their checkboxes.
greatpie/smart-contract-audit-skill
Script-backed, out-of-box auditing workflow for Solidity/EVM repositories based on EVMbench detect/patch/exploit methodology.
Gabson0x/bountyforge
Security audit of Solidity code while you develop. An agent skill from Gabson0x/bountyforge.
sablier-labs/evm-monorepo
Verify smart contracts on Etherscan, Routescan, and Blockscout block explorers.
quillai-network/quillshield_skills
Token-efficient smart contract security auditing via Behavioral State Analysis (BSA).
quillai-network/quillshield_skills
Detects Denial of Service and griefing vulnerabilities in smart contracts.
quillai-network/quillshield_skills
Detects input validation failures and arithmetic vulnerabilities in smart contracts.
quillai-network/quillshield_skills
Detects price oracle manipulation and flash loan attack vectors in DeFi smart contracts.
quillai-network/quillshield_skills
Detects vulnerabilities in upgradeable proxy smart contracts including storage layout collisions, uninitialized implementations, function selector clashing, delegatecall context issues, and upgrade…
quillai-network/quillshield_skills
Systematically detects all reentrancy vulnerability variants in smart contracts — classic, cross-function, cross-contract, and read-only reentrancy.
Works with
Categories
Detects unsafe external call patterns and token integration vulnerabilities in smart contracts. External Call Safety is an agent skill from quillai-network/quillshield_skills. Detects unsafe external call patterns and token integration vulnerabilities in smart contracts.
External Call Safety fits situations like: auditing contracts that interact with external contracts; integrate arbitrary ERC20 tokens; distribute payments; make low-level calls.
Run `npx skills add quillai-network/quillshield_skills --skill external-call-safety -a claude-code`. Or copy the skill folder (plugins/external-call-safety/skills/external-call-safety in quillai-network/quillshield_skills) into .claude/skills/external-call-safety in your project. Claude Code loads it when a task matches its description.
Run `npx skills add quillai-network/quillshield_skills --skill external-call-safety -a codex`. Or copy the skill folder (plugins/external-call-safety/skills/external-call-safety in quillai-network/quillshield_skills) into .agents/skills/external-call-safety in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add quillai-network/quillshield_skills --skill external-call-safety -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/external-call-safety, .gemini/skills/external-call-safety, .github/skills/external-call-safety and .opencode/skills/external-call-safety in your project.
SKILL.md names no scripts, command-line tools or credentials: External Call Safety is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
External Call Safety is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.1k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 3.4k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with External Call Safety: Stellar iOS Mac SDK (Soneso/stellar-ios-mac-sdk, 132 stars), Smart Contract Audit (forefy/.context, 152 stars), Fizz Convert (pashov/skills, 1.2k stars) and Smart Contract Audit (greatpie/smart-contract-audit-skill, 101 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
quillai-network (a GitHub organization) maintains it in quillai-network/quillshield_skills, which has 130 GitHub stars. The repository holds 11 skills in this directory. The repository was last updated on March 30, 2026.
Source: quillai-network/quillshield_skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.