---
name: crane-camelot
description: This skill should be used when the user asks about "Camelot integration", "Camelot swap", "Camelot liquidity", "Camelot V2", "fee-on-transfer tokens", "asymmetric fees", "directional fees", or needs to interact with Camelot DEX on Arbitrum using Crane's service library.
license: MIT
---
# Crane Camelot V2 Integration
Crane provides Camelot V2 integration with service library, stubs, and test infrastructure. Camelot differs from standard Uniswap V2 forks by supporting asymmetric (directional) fees.
## Components
| Component | Location | Purpose |
|-----------|----------|---------|
| `CamelotV2Service` | `services/CamelotV2Service.sol` | Swap, deposit, withdraw operations |
| `CamelotV2RouterAwareRepo` | `CamelotV2RouterAwareRepo.sol` | Router dependency injection |
| `CamelotV2FactoryAwareRepo` | `CamelotV2FactoryAwareRepo.sol` | Factory dependency injection |
| `TestBase_CamelotV2` | `test/bases/TestBase_CamelotV2.sol` | Full protocol deployment |
## Key Difference: Asymmetric Fees
Camelot pools have **directional fees** - different fees for each swap direction:
```solidity
// Camelot's getReserves returns fees for each direction
(uint112 reserve0, uint112 reserve1, uint16 token0feePercent, uint16 token1FeePercent) = pool.getReserves();
// token0feePercent: Fee when swapping token0 -> token1
// token1FeePercent: Fee when swapping token1 -> token0
```
## Quick Start: Execute Swap
```solidity
import {CamelotV2Service} from "@crane/contracts/protocols/dexes/camelot/v2/services/CamelotV2Service.sol";
import {ICamelotV2Router} from "@crane/contracts/interfaces/protocols/dexes/camelot/v2/ICamelotV2Router.sol";
import {ICamelotPair} from "@crane/contracts/interfaces/protocols/dexes/camelot/v2/ICamelotPair.sol";
contract CamelotSwapper {
ICamelotV2Router public router;
function swap(
ICamelotPair pool,
IERC20 tokenIn,
IERC20 tokenOut,
uint256 amountIn
) external returns (uint256 amountOut) {
tokenIn.transferFrom(msg.sender, address(this), amountIn);
amountOut = CamelotV2Service._swap(
router,
pool,
amountIn,
tokenIn,
tokenOut,
address(0) // referrer (optional)
);
}
}
```
## Service Operations
### Deposit (Add Liquidity)
```solidity
function _deposit(
ICamelotV2Router router,
IERC20 tokenA,
IERC20 tokenB,
uint256 amountADesired,
uint256 amountBDesired
) internal returns (uint256 liquidity);
```
### Withdraw (Remove Liquidity)
```solidity
// Direct withdrawal (no router)
function _withdrawDirect(
ICamelotPair pool,
uint256 amt
) internal returns (uint256 amount0, uint256 amount1);
```
### Swap
```solidity
// Swap with pool auto-detection
function _swap(
ICamelotV2Router router,
ICamelotPair pool,
uint256 amountIn,
IERC20 tokenIn,
IERC20 tokenOut,
address referrer
) internal returns (uint256 amountOut);
// Swap with explicit reserves and fees
function _swap(
ICamelotV2Router router,
uint256 amountIn,
IERC20 tokenIn,
uint256 reserveIn,
uint256 feePercent,
IERC20 tokenOut,
uint256 reserveOut,
address referrer
) internal returns (uint256 amountOut);
```
### Swap and Deposit (Zap In)
```solidity
function _swapDeposit(
ICamelotV2Router router,
ICamelotPair pool,
IERC20 tokenIn,
uint256 saleAmt,
IERC20 opToken,
address referrer
) internal returns (uint256 lpAmount);
```
### Withdraw and Swap (Zap Out)
```solidity
function _withdrawSwapDirect(
ICamelotPair pool,
ICamelotV2Router router,
uint256 amt,
IERC20 tokenOut,
IERC20 opToken,
address referrer
) internal returns (uint256 amountOut);
```
## Reserve Sorting
Get reserves sorted by known token:
```solidity
(
uint256 knownReserve,
uint256 opposingReserve,
uint256 knownFeePercent,
uint256 opposingFeePercent
) = CamelotV2Service._sortReserves(pool, knownToken);
```
## Testing
```solidity
import {TestBase_CamelotV2} from "@crane/contracts/protocols/dexes/camelot/v2/test/bases/TestBase_CamelotV2.sol";
contract MyTest is TestBase_CamelotV2 {
function setUp() public override {
super.setUp();
// camelotV2Factory and camelotV2Router available
}
function test_swap() public {
// Create pair
address pair = camelotV2Factory.createPair(
address(tokenA),
address(tokenB)
);
// Add liquidity
CamelotV2Service._deposit(
camelotV2Router,
tokenA,
tokenB,
1000e18,
1000e18
);
// Execute swap
uint256 amountOut = CamelotV2Service._swap(
camelotV2Router,
ICamelotPair(pair),
100e18,
tokenA,
tokenB,
address(0)
);
}
}
```
## Fee-on-Transfer Token Support
Camelot uses `swapExactTokensForTokensSupportingFeeOnTransferTokens` to support deflationary tokens:
```solidity
router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
amountIn,
amountOutMin,
path,
to,
referrer,
deadline
);
```
## File Organization
```
contracts/protocols/dexes/camelot/v2/
├── services/
│ └── CamelotV2Service.sol
├── CamelotV2RouterAwareRepo.sol
├── CamelotV2FactoryAwareRepo.sol
├── stubs/
│ ├── CamelotFactory.sol
│ ├── CamelotRouter.sol
│ ├── CamelotPair.sol
│ └── libraries/
│ ├── Math.sol
│ ├── SafeMath.sol
│ └── UniswapV2Library.sol
└── test/bases/
└── TestBase_CamelotV2.sol
```
## Additional Resources
### Reference Files
- **`references/camelot-services.md`** - Detailed patterns and examples