帮助审查 Solidity AMM、流动池与交换流程中的常见安全风险与检查项
复制安装指令,让 AI 自动完成配置 · 推荐新手
请帮我安装 askskill 上的 "defi-amm-security" 技能: 1. 下载 https://raw.githubusercontent.com/affaan-m/ECC/main/skills/defi-amm-security/SKILL.md 2. 保存为 ~/.claude/skills/defi-amm-security/SKILL.md 3. 装好后重载技能,告诉我可以用了
请为这份 Solidity AMM 合约做安全检查,重点检查重入、CEI 顺序、整数计算、滑点保护、管理员权限以及可能的捐赠或通胀攻击,并按严重程度列出问题与修复建议。
一份按风险等级整理的安全问题清单,并附带修复建议与审查重点说明。
我正在设计一个流动池合约,请根据 AMM 安全清单检查是否存在预言机操纵、份额增发、储备计算错误和提现流程漏洞,并给出需要补充的防护措施。
针对流动池结构的漏洞分析,以及应补充的防护机制与实现建议。
请审查这个 swap 流程的安全性,分析价格操纵、滑点设置、外部调用顺序、状态更新时机和权限控制是否合理,并输出一份上线前检查清单。
一份面向上线前的交换流程安全检查清单,包含风险点与验证步骤。
Critical vulnerability patterns and hardened implementations for Solidity AMM contracts, LP vaults, and swap functions.
token.balanceOf(address(this)) in share or reserve mathUse this as a checklist-plus-pattern library. Review every user entrypoint against the categories below and prefer the hardened examples over hand-rolled variants.
The shell commands in this skill are local audit examples. Run them only in a trusted checkout or disposable sandbox, and do not splice untrusted contract names, paths, RPC URLs, private keys, or user-supplied flags into shell commands. Ask before installing tools or running long fuzzing/static-analysis jobs that may consume significant local or paid resources.
Never include secrets, private keys, seed phrases, API tokens, or mainnet signing credentials in command examples, logs, or reports.
Vulnerable:
function withdraw(uint256 amount) external {
require(balances[msg.sender] >= amount);
token.transfer(msg.sender, amount);
balances[msg.sender] -= amount;
}
Safe:
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
using SafeERC20 for IERC20;
function withdraw(uint256 amount) external nonReentrant {
require(balances[msg.sender] >= amount, "Insufficient");
balances[msg.sender] -= amount;
token.safeTransfer(msg.sender, amount);
}
Do not write your own guard when a hardened library exists.
Using token.balanceOf(address(this)) directly for share math lets attackers manipulate the denominator by sending tokens to the contract outside the intended path.
// Vulnerable
function deposit(uint256 assets) external returns (uint256 shares) {
shares = (assets * totalShares) / token.balanceOf(address(this));
}
// Safe
uint256 private _totalAssets;
function deposit(uint256 assets) external nonReentrant returns (uint256 shares) {
uint256 balBefore = token.balanceOf(address(this));
token.safeTransferFrom(msg.sender, address(this), assets);
uint256 received = token.balanceOf(address(this)) - balBefore;
shares = totalShares == 0 ? received : (received * totalShares) / _totalAssets;
_totalAssets += received;
totalShares += shares;
}
Track internal accounting and measure actual tokens received.
Spot prices are flash-loan manipulable. Prefer TWAP.
uint32[] memory secondsAgos = new uint32[](2);
secondsAgos[0] = 1800;
secondsAgos[1] = 0;
(int56[] memory tickCumulatives,) = IUniswapV3Pool(pool).observe(secondsAgos);
int24 twapTick = int24(
(tickCumulatives[1] - tickCumulatives[0]) / int56(uint56(30 minutes))
);
uint160 sqrtPriceX96 = TickMath.getSqrtRatioAtTick(twapTick);
Every swap path needs caller-provided slippage and a deadline.
function swap(
uint256 amountIn,
uint256 amountOutMin,
uint256 deadline
) external returns (uint256 amountOut) {
require(block.timestamp <= deadline, "Expired");
amountOut = _calculateOut(amountIn);
require(amountOut >= amountOutMin, "Slippage exceeded");
_executeSwap(amountIn, amountOut);
}
import {FullMath} from "@uniswap/v3-core/contracts/libraries/FullMath.sol";
uint256 result = FullMath.mulDiv(a, b, c);
For large reserve math, avoid naive a * b / c when overflow risk exists.
…
为 Quarkus 项目执行发布前验证闭环,涵盖构建、测试、扫描与差异审查。
在 Solana 交易前评估代币协同行为与跑路风险,输出退出流动性风险结论。