Smart Contracts
สถาปัตยกรรม Contract
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ JVAULT.sol │ │ VaultManager │ │ Timelock.sol │
│ (ERC-20) │────│ .sol │────│ (Governance) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │
│ │
┌─────────────────┐ ┌─────────────────┐
│ WithdrawQueue │ │ PriceOracle │
│ .sol │ │ .sol │
└─────────────────┘ └─────────────────┘
Contract หลัก
JVAULT.sol (Token หลัก)
solidity
// ที่อยู่ Contract: 0x... (TODO: Deploy)
// เครือข่าย: Base L2
interface IJVAULT {
function deposit(uint256 amount, uint256 lockDays) external;
function requestWithdrawal(uint256 shares) external;
function processWithdrawals() external;
function updateNAV(uint256 newNAV) external;
function getCurrentNAV() external view returns (uint256);
}
ฟังก์ชันหลัก
deposit(uint256 amount, uint256 lockDays)
- ฝาก USDC และออก JVAULT tokens
- ตรวจสอบระยะเวลาล็อค (7, 30, 60, 90 วัน)
- ใช้ค่าธรรมเนียมฝาก 0.25%
- ปล่อย event
Deposit
requestWithdrawal(uint256 shares)
- เข้าคิว JVAULT tokens สำหรับการถอนวันอาทิตย์
- ล็อค tokens จนกว่าจะตัดรอบ
- ไม่สามารถยกเลิกเมื่อส่งแล้ว
- ปล่อย event
WithdrawalRequested
processWithdrawals()
- ฟังก์ชันเฉพาะ Keeper
- ประมวลผลการถอนที่รออยู่ทั้งหมด
- เผา JVAULT tokens
- โอน USDC ให้ผู้ใช้
- เรียกทุกวันอาทิตย์ 00:00 UTC
updateNAV(uint256 newNAV)
- ฟังก์ชันเฉพาะ Keeper
- อัปเดตราคา token ตามผลงาน vault
- ตรวจสอบราคาในขอบเขตที่สมเหตุสมผล
- ปล่อย event
NAVUpdated
Events
solidity
event Deposit(
address indexed user,
uint256 usdcAmount,
uint256 sharesIssued,
uint256 lockUntil,
uint256 pointsEarned
);
event WithdrawalRequested(
address indexed user,
uint256 sharesAmount,
uint256 requestId
);
event WithdrawalProcessed(
address indexed user,
uint256 sharesAmount,
uint256 usdcAmount,
uint256 requestId
);
event NAVUpdated(
uint256 oldNAV,
uint256 newNAV,
uint256 timestamp
);
ตัวแปร State
solidity
contract JVAULT is ERC20 {
IERC20 public usdc;
uint256 public currentNAV;
uint256 public totalDeposits;
uint256 public totalWithdrawals;
uint256 public constant FEE_BASIS_POINTS = 25; // 0.25%
mapping(address => UserInfo) public userInfo;
mapping(uint256 => WithdrawalRequest) public withdrawalQueue;
struct UserInfo {
uint256 lockedUntil;
uint256 totalPoints;
uint256 lastDeposit;
}
struct WithdrawalRequest {
address user;
uint256 shares;
uint256 timestamp;
bool processed;
}
}
การควบคุมการเข้าถึง
บทบาท | สิทธิ์ | ที่อยู่ |
---|---|---|
Owner | หยุดฉุกเฉิน อัปเกรด | 0x... (Multisig) |
Keeper | อัปเดต NAV ประมวลผลการถอน | 0x... (Bot) |
Admin | เปลี่ยนพารามิเตอร์ | 0x... (Timelock) |
ฟีเจอร์ความปลอดภัย
การป้องกัน Reentrancy
- OpenZeppelin
ReentrancyGuard
- การเรียกภายนอกทั้งหมดได้รับการป้องกัน
- บังคับใช้รูปแบบ CEI
การดำเนินงานที่หยุดได้
- ฟังก์ชันหยุดฉุกเฉิน
- การฝาก/ถอนสามารถหยุดได้
- การดำเนินงาน Keeper ได้รับการป้องกัน
Time Locks
- การเปลี่ยนแปลงพารามิเตอร์สำคัญต้องใช้เวลา 48 ชม.
- ระยะเวลาแจ้งชุมชน
- ความสามารถแทนที่ฉุกเฉิน
ที่อยู่ที่ Deploy แล้ว
Contract | ที่อยู่ Base L2 | สถานะ |
---|---|---|
JVAULT | 0x... | TODO: Deploy |
VaultManager | 0x... | TODO: Deploy |
USDC | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | ✅ Live |
การตรวจสอบ
Contract ทั้งหมดจะเป็น:
- ✅ โอเพ่นซอร์ส
- ✅ ตรวจสอบแล้วบน Basescan
- ✅ ตรวจสอบโดยบริษัทที่มีชื่อเสียง
- ✅ การตรวจสอบอย่างเป็นทางการสำหรับฟังก์ชันสำคัญ
การรวม
ไลบรารี Web3
javascript
// ใช้ wagmi + viem
import { useContract, useContractWrite } from 'wagmi';
const { write: deposit } = useContractWrite({
address: JVAULT_ADDRESS,
abi: JVAULT_ABI,
functionName: 'deposit',
});
การเรียก Contract โดยตรง
javascript
// ใช้ ethers.js
const jvault = new ethers.Contract(address, abi, signer);
await jvault.deposit(amount, lockDays);
ก่อนหน้า: ← ปัจจัยความเสี่ยง | ถัดไป: ระบบ Keeper →