Skip to content
Merged
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
13 changes: 13 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
; Submodule declarations for the Charon workspace.
;
; forge-std is pinned by gitlink to an exact commit — we deliberately do NOT
; set a `branch = ...` line. Omitting `branch` means `git submodule update`
; (without `--remote`) always checks out the commit recorded in the parent
; repo's index, which is reproducible across machines and CI runs.
;
; Current pin: 2999b6563e1f07971a09d48b82f3fac910d72a05 (v1.15.0 + 15)
; Bumping the pin requires a commit that updates the gitlink; do not run
; `git submodule update --remote` in CI.
[submodule "contracts/lib/forge-std"]
path = contracts/lib/forge-std
url = https://github.com/foundry-rs/forge-std
7 changes: 7 additions & 0 deletions contracts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Foundry build artifacts
out/
cache/
broadcast/

# Local dev
.env
30 changes: 30 additions & 0 deletions contracts/foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc_version = "0.8.24"
# BNB Chain's EVM is still at the Paris hard fork — it has not enabled the
# Shanghai PUSH0 opcode. Without `evm_version = "paris"` the compiler emits
# PUSH0 bytecode (default for solc >= 0.8.20) and deployed contracts revert
# on first touch. This setting is load-bearing for v0.1 BSC-only scope.
evm_version = "paris"
optimizer = true
optimizer_runs = 1_000_000
via_ir = false
remappings = [
"forge-std/=lib/forge-std/src/",
]

# Forge fmt — 100-char width, 4-space indent — matches the Rust side.
[fmt]
line_length = 100
tab_width = 4
bracket_spacing = true

# Fork-test endpoint for BSC mainnet — `BNB_HTTP_URL` from the repo
# `.env`. Aliased here so test scripts can pass `--fork-url bnb`.
[rpc_endpoints]
bnb = "${BNB_HTTP_URL}"

[etherscan]
bnb = { key = "${BSCSCAN_API_KEY}", chain = 56 }
1 change: 1 addition & 0 deletions contracts/lib/forge-std
Submodule forge-std added at 2999b6
275 changes: 275 additions & 0 deletions contracts/src/CharonLiquidator.sol

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions contracts/src/interfaces/IAaveV3Pool.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

/// @title IAaveV3Pool
/// @notice Stub interface for the Aave V3 Pool contract deployed on BNB Chain.
/// @dev Only the entry points required by CharonLiquidator v0.1 are declared here.
/// Additional methods (liquidationCall, supply, withdraw, etc.) will be added in
/// future commits as the implementation grows.
/// BNB Chain mainnet Pool proxy: 0x6807dc923806fE8Fd134338EABCA509979a7e08
interface IAaveV3Pool {
/// @notice Allows a smart contract to access the liquidity of the pool within one transaction,
/// as long as the amount taken plus a fee is returned.
/// @dev The receiving contract must implement IFlashLoanSimpleReceiver and repay in executeOperation.
/// @param receiverAddress The address of the contract that will receive the flash-loaned funds
/// and must implement IFlashLoanSimpleReceiver.
/// @param asset The address of the ERC-20 asset to flash-borrow.
/// @param amount The amount to flash-borrow.
/// @param params Variadic packed params to pass to the receiver as extra information.
/// @param referralCode The code used to register the integrator for the referral program.
/// Pass 0 if no referral.
function flashLoanSimple(
address receiverAddress,
address asset,
uint256 amount,
bytes calldata params,
uint16 referralCode
) external;
}
31 changes: 31 additions & 0 deletions contracts/src/interfaces/IERC20.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

/// @title IERC20
/// @notice Minimal ERC-20 interface required by CharonLiquidator.
/// @dev Only the subset of ERC-20 that the liquidator and rescue logic directly call.
/// Full transfer/approval events are omitted here — they are emitted by token contracts.
interface IERC20 {
/// @notice Returns the token balance of `account`.
/// @param account The address to query.
/// @return The token balance.
function balanceOf(address account) external view returns (uint256);

/// @notice Transfers `amount` tokens to `to` from the caller.
/// @param to Recipient address.
/// @param amount Number of tokens to send.
/// @return True on success (non-standard tokens may revert instead).
function transfer(address to, uint256 amount) external returns (bool);

/// @notice Approves `spender` to spend up to `amount` of the caller's tokens.
/// @param spender The address being approved.
/// @param amount The allowance ceiling.
/// @return True on success.
function approve(address spender, uint256 amount) external returns (bool);

/// @notice Returns the remaining allowance that `spender` may transfer on behalf of `owner`.
/// @param owner The token holder.
/// @param spender The approved spender.
/// @return The remaining allowance.
function allowance(address owner, address spender) external view returns (uint256);
}
25 changes: 25 additions & 0 deletions contracts/src/interfaces/IFlashLoanSimpleReceiver.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

/// @title IFlashLoanSimpleReceiver
/// @notice Aave V3 flash-loan simple receiver callback interface.
/// @dev Implementors MUST repay asset + premium to the Aave Pool within the same transaction.
/// Reference: https://github.com/aave/aave-v3-core/blob/master/contracts/flashloan/interfaces/IFlashLoanSimpleReceiver.sol
interface IFlashLoanSimpleReceiver {
/// @notice Executes an operation after receiving a flash-loaned asset.
/// @dev Called by the Aave V3 Pool after funds are transferred. The callee must
/// repay `amount + premium` of `asset` back to the pool before this returns.
/// @param asset The address of the flash-loaned ERC-20 token.
/// @param amount The amount that was flash-loaned.
/// @param premium The fee owed on top of `amount`.
/// @param initiator The address that initiated the flash loan (must equal address(this) for CharonLiquidator).
/// @param params Arbitrary bytes passed by the initiator — used to forward LiquidationParams.
/// @return True if the operation succeeded; the pool reverts if false is returned.
function executeOperation(
address asset,
uint256 amount,
uint256 premium,
address initiator,
bytes calldata params
) external returns (bool);
}
37 changes: 37 additions & 0 deletions contracts/src/interfaces/IVToken.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

/// @title IVToken
/// @notice Stub interface for Venus Protocol vToken contracts on BNB Chain.
/// @dev Only the entry points required by CharonLiquidator v0.1 are declared.
/// Venus vTokens follow the Compound V2 cToken model.
/// Additional methods (mint, redeem, borrow, borrowBalanceCurrent, etc.) will be
/// added in future commits as the implementation grows.
/// Venus Comptroller (unitroller) on BNB Chain: 0xfD36E2c2a6789Db23113685031d7F16329158384
interface IVToken {
/// @notice The caller repays `repayAmount` of the underlying asset on behalf of `borrower`
/// and seizes `vTokenCollateral` from the borrower in return.
/// @dev Caller must have pre-approved this contract to spend `repayAmount` of the debt token.
/// Returns an error code (0 = success) following the Compound V2 convention.
/// Reverts on failure in more recent Venus deployments.
/// @param borrower The account whose borrow is being repaid.
/// @param repayAmount The amount of the underlying debt asset to repay.
/// @param vTokenCollateral The vToken address of the collateral to seize.
/// @return 0 on success, non-zero error code on failure.
function liquidateBorrow(address borrower, uint256 repayAmount, address vTokenCollateral)
external
returns (uint256);

/// @notice Redeems vTokens for the specified amount of the underlying asset.
/// @dev Returns an error code (0 = success). The caller must hold at least enough vTokens
/// to cover `redeemAmount` of underlying after conversion.
/// @param redeemAmount The amount of underlying asset to receive.
/// @return 0 on success, non-zero error code on failure.
function redeemUnderlying(uint256 redeemAmount) external returns (uint256);

/// @notice Returns the vToken balance of `account`.
/// @dev Used by rescue() to validate amounts before pulling vTokens out of the contract.
/// @param account The address to query.
/// @return The vToken balance (in vToken units, not underlying).
function balanceOf(address account) external view returns (uint256);
}
Loading