Phiên bản: 3.0.0 Ngày cập nhật: 2025 Đơn vị: GoldVN Invest — https://goldvninvest.online Công nghệ: Solidity 0.8.20 · BSC Mainnet · Hardhat Hành lang pháp lý: Nghị quyết 05/2025/NQ-CP · Luật 71/2025/QH15
backend/ecosystem/smart-contracts/gvi/
├── contracts/
│ ├── GIVToken.sol ← Token quản trị nội bộ (GIV)
│ ├── VNLToken.sol ← Stablecoin 1:1 VND — kết nối ngân hàng
│ ├── GIVGovernance.sol ← dPoS oracle định giá GIV ±7%
│ ├── EmergencyCircuitBreaker.sol ← Cơ chế ngắt khẩn cấp (Bộ Tài chính)
│ └── InvestorWhitelist.sol ← Kiểm soát KYC on-chain (Điều 6/7 NQ-05)
├── scripts/
│ ├── deploy.js
│ └── verify.js
├── hardhat.config.js
└── README.md
backend/ecosystem/smart-contracts/gvi/README.md- Kiến trúc hệ thống đầy đủ:
docs/newproject001.md- Đề án kỹ thuật:
docs/GVI-NETWORK-TECHNICAL-PROPOSAL.md
GVI Network là sàn giao dịch tài sản kỹ thuật số hoạt động trong khuôn khổ thí điểm 5 năm theo:
| Văn bản | Nội dung áp dụng |
|---|---|
| Nghị quyết 05/2025/NQ-CP | Cơ chế thí điểm sàn giao dịch tài sản mã hóa tại Việt Nam |
| Luật 71/2025/QH15 | Công nhận tài sản số, nghĩa vụ thuế, bảo vệ pháp lý |
| Luật AML/CFT Việt Nam | Phòng chống rửa tiền, sàng lọc nhà đầu tư |
| TCVN 11930:2017 | An toàn thông tin Cấp độ 4 |
Vốn điều lệ: 2 tỷ VND (GCNĐKDN số 0111319828 — TP Hà Nội, 19/12/2025)
Nguồn doanh thu hợp pháp:
├── Phí giao dịch Spot CEX (maker/taker fee)
├── Phí giao dịch P2P (escrow commission)
├── Phí giao dịch Futures
├── Phí niêm yết ICO/ITO (Mẫu 01 — bản cáo bạch)
├── Phí NFT Marketplace (royalty + listing)
└── Phí dịch vụ Staking / Lending Pool
Quản lý dòng tiền:
└── 100% giao dịch VND qua tài khoản ngân hàng chuyên dùng
→ Ngân hàng đối tác được NHNN cấp phép
→ Kết nối NAPAS/IBFT — minh bạch, kiểm soát được
| Vai trò | Chức năng cụ thể |
|---|---|
| Quản trị token GIV | Cơ chế mở khóa theo volume giao dịch thực tế |
| Cổng VNL — stablecoin VND | Định danh dòng tiền nạp/rút, kết nối ngân hàng |
| Kiểm soát nhà đầu tư | Whitelist KYC on-chain theo Điều 6/7 NQ-05 |
| Ngắt khẩn cấp | Circuit breaker theo yêu cầu Bộ Tài chính |
| Bằng chứng pháp lý | Events on-chain bất biến — kiểm toán độc lập |
╔═══════════════════════════════════════════════════════════════════╗
║ NHÀ ĐẦU TƯ (đã KYC/eKYC — Điều 6/7 NQ-05) ║
║ Tài khoản ngân hàng thương mại trong nước ║
╚══════════════════════════╤════════════════════════════════════════╝
│ [Nạp tiền VND → NAPAS/IBFT]
▼
╔═══════════════════════════════════════════════════════════════════╗
║ TẦNG 1: KYC/AML — InvestorWhitelist (on-chain) ║
║ • Đồng bộ từ DB: kycApplication.status = APPROVED ║
║ • Phân loại: DOMESTIC / FOREIGN (Điều 6/7 NQ-05) ║
║ • AML status: CLEAR / FLAGGED / REVIEW_REQUIRED ║
║ • Tái xác thực: 365 ngày ║
╚══════════════════════════╤════════════════════════════════════════╝
│ [isEligible() = true]
▼
╔═══════════════════════════════════════════════════════════════════╗
║ TẦNG 2: VNLToken — Stablecoin 1:1 VND ║
║ • Mint khi ngân hàng xác nhận nạp tiền thành công ║
║ • AML quota: giới hạn theo hạn mức phê duyệt ║
║ • Burn khi rút tiền về ngân hàng ║
║ • Tuân thủ Điều 15 NQ-05: tách biệt quỹ KH / quỹ sàn ║
╚══════════════════════════╤════════════════════════════════════════╝
│ [VNL giao dịch trên sàn]
▼
╔═══════════════════════════════════════════════════════════════════╗
║ TẦNG 3: Order Matching Engine (CEX/DEX/P2P) ║
║ • assertTradingAllowed() — EmergencyCircuitBreaker ║
║ • GIVToken.unlockTokens() — Mở khóa GIV theo volume ║
║ • triggerTaxOnTransaction() — Thuế Luật 71/2025/QH15 ║
╚══════════════════════════╤════════════════════════════════════════╝
│ [Events bất biến on-chain]
▼
┌──────────────────────┐
│ BSCScan Explorer │
│ bscscan.com/tx/... │
│ Thanh tra Bộ TC │
│ tra cứu bất kỳ lúc │
└──────────────────────┘
File:
contracts/GIVToken.solVai trò: Token quản trị nội bộ — mở khóa theo volume giao dịch thực tế (hệ số α)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title GIVToken
* @notice Token quản trị GVI Network — mở khóa theo volume giao dịch VNL
* @dev Tuân thủ NQ-05/2025/NQ-CP: không phải chứng khoán, không phải tiền pháp định
* Hệ số α được quản trị bởi givUnlockConfig trong DB (off-chain governance)
*/
contract GIVToken {
string public constant name = "GoldVN Invest Token";
string public constant symbol = "GIV";
uint8 public constant decimals = 18;
uint256 public totalSupply;
address public owner;
address public escrowEngine; // Backend GVI được ủy quyền
mapping(address => uint256) public balanceOf;
mapping(address => uint256) public lockedBalance;
mapping(address => mapping(address => uint256)) public allowance;
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
event TokensLocked(address indexed account, uint256 amount, string reason);
event TokensUnlocked(address indexed account, uint256 amount);
event EscrowEngineSet(address indexed engine);
modifier onlyOwner() { require(msg.sender == owner, "GIV: not owner"); _; }
modifier onlyEscrow() { require(msg.sender == escrowEngine, "GIV: not escrow"); _; }
constructor(uint256 initialSupply) {
owner = msg.sender;
totalSupply = initialSupply * 10**18;
balanceOf[msg.sender] = totalSupply;
emit Transfer(address(0), msg.sender, totalSupply);
}
function setEscrowEngine(address engine) external onlyOwner {
require(engine != address(0), "GIV: zero address");
escrowEngine = engine;
emit EscrowEngineSet(engine);
}
/// @notice Khóa GIV theo lịch vesting — gọi khi phát hành ICO/ITO
function lockTokens(address account, uint256 amount, string calldata reason)
external onlyOwner
{
require(balanceOf[account] >= amount, "GIV: insufficient balance");
balanceOf[account] -= amount;
lockedBalance[account] += amount;
emit TokensLocked(account, amount, reason);
}
/// @notice Mở khóa GIV — gọi từ backend sau khi volume giao dịch đủ điều kiện
function unlockTokens(address account, uint256 amount) external onlyEscrow {
require(lockedBalance[account] >= amount, "GIV: insufficient locked");
lockedBalance[account] -= amount;
balanceOf[account] += amount;
emit TokensUnlocked(account, amount);
}
function transfer(address to, uint256 amount) external returns (bool) {
require(balanceOf[msg.sender] >= amount, "GIV: insufficient balance");
balanceOf[msg.sender] -= amount;
balanceOf[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
function approve(address spender, uint256 amount) external returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transferFrom(address from, address to, uint256 amount) external returns (bool) {
require(balanceOf[from] >= amount, "GIV: insufficient balance");
require(allowance[from][msg.sender] >= amount, "GIV: insufficient allowance");
allowance[from][msg.sender] -= amount;
balanceOf[from] -= amount;
balanceOf[to] += amount;
emit Transfer(from, to, amount);
return true;
}
}
File:
contracts/VNLToken.solVai trò: Stablecoin 1:1 VND — cổng xác định dòng tiền nạp/rút
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title VNLToken
* @notice Stablecoin nội bộ 1 VNL = 1 VND — cổng kết nối hệ thống ngân hàng
* @dev Tuân thủ Điều 15 NQ-05: mint chỉ khi ngân hàng xác nhận nạp tiền thành công
* AML quota theo quy định NHNN và Luật PCRT
*/
contract VNLToken {
string public constant name = "VNL Token";
string public constant symbol = "VNL";
uint8 public constant decimals = 0; // 1 VNL = 1 VND
uint256 public totalSupply;
address public owner; // GVI Admin (Multisig)
address public escrowEngine; // Backend oracle được ủy quyền
mapping(address => uint256) public balanceOf;
mapping(address => bool) public isFrozen; // AML freeze
mapping(address => uint256) public approvedQuota; // Hạn mức AML
event Transfer(address indexed from, address indexed to, uint256 amount);
event VNLMinted(address indexed to, uint256 amount, string bankRef);
event VNLBurned(address indexed from, uint256 amount);
event AccountFrozen(address indexed account, bool status);
event QuotaSet(address indexed account, uint256 quota);
modifier onlyOwner() { require(msg.sender == owner, "VNL: not owner"); _; }
modifier onlyEscrow() { require(msg.sender == escrowEngine, "VNL: not escrow"); _; }
modifier notFrozen(address a) {
require(!isFrozen[a], "VNL: account frozen — AML compliance");
_;
}
constructor() { owner = msg.sender; }
function setEscrowEngine(address engine) external onlyOwner {
require(engine != address(0), "VNL: zero address");
escrowEngine = engine;
}
/// @notice Phong tỏa/mở băng tài khoản vi phạm AML
function freezeAccount(address account, bool status) external onlyOwner {
isFrozen[account] = status;
emit AccountFrozen(account, status);
}
/// @notice Cấp hạn mức giao dịch theo quy định AML (0 = không giới hạn)
function setQuota(address account, uint256 quota) external onlyOwner {
approvedQuota[account] = quota;
emit QuotaSet(account, quota);
}
/// @notice Mint VNL khi ngân hàng xác nhận nạp tiền thành công
/// bankRef = mã tham chiếu giao dịch ngân hàng (NAPAS/IBFT ref)
function mintForDeposit(
address to,
uint256 amount,
string calldata bankRef
) external onlyEscrow notFrozen(to) {
require(
approvedQuota[to] == 0 || amount <= approvedQuota[to],
"VNL: exceeds approved quota"
);
totalSupply += amount;
balanceOf[to] += amount;
emit Transfer(address(0), to, amount);
emit VNLMinted(to, amount, bankRef);
}
/// @notice Burn VNL khi nhà đầu tư rút tiền về ngân hàng
function burnForWithdraw(uint256 amount) external notFrozen(msg.sender) {
require(balanceOf[msg.sender] >= amount, "VNL: insufficient balance");
balanceOf[msg.sender] -= amount;
totalSupply -= amount;
emit Transfer(msg.sender, address(0), amount);
emit VNLBurned(msg.sender, amount);
}
function transfer(address to, uint256 amount)
external notFrozen(msg.sender) notFrozen(to) returns (bool)
{
require(balanceOf[msg.sender] >= amount, "VNL: insufficient balance");
balanceOf[msg.sender] -= amount;
balanceOf[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
}
File:
contracts/GIVGovernance.solVai trò: dPoS oracle định giá GIV — biên độ ±7% ngăn thao túng giá
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title GIVGovernance
* @notice Cơ chế quản trị định giá GIV — weighted-average từ mạng Validator
* @dev Mỗi Validator vote 1 lần/24h; biên độ ±7% chống thao túng
* Kết quả đồng bộ vào DB qua givGovernanceService.ts
*/
contract GIVGovernance {
address public admin;
uint256 public currentGIVPrice;
uint256 public constant MAX_DEVIATION = 7; // ±7%
uint256 public minShare;
struct Validator {
uint256 shares;
bool isActive;
uint256 lastVotedPrice;
uint256 lastVoteAt;
}
mapping(address => Validator) public validators;
address[] public validatorList;
event PriceVoted(address indexed validator, uint256 price, uint256 timestamp);
event PriceAggregated(uint256 newPrice, uint256 voterCount, uint256 timestamp);
event ValidatorUpdated(address indexed validator, uint256 shares, bool active);
modifier onlyAdmin() { require(msg.sender == admin, "GIVGov: not admin"); _; }
constructor(uint256 _minShare, uint256 _initialPrice) {
admin = msg.sender;
minShare = _minShare;
currentGIVPrice = _initialPrice;
}
/// @notice Validator vote giá GIV (1 lần/24h, trong biên độ ±7%)
/// @param proposedPrice Giá GIV × 100 (VD: 25000 = 250.00 VND/GIV)
function submitGIVPrice(uint256 proposedPrice) external {
Validator storage v = validators[msg.sender];
require(v.isActive, "GIVGov: not active validator");
require(block.timestamp >= v.lastVoteAt + 1 days, "GIVGov: one vote per 24h");
if (currentGIVPrice > 0) {
uint256 maxP = currentGIVPrice * (100 + MAX_DEVIATION) / 100;
uint256 minP = currentGIVPrice * (100 - MAX_DEVIATION) / 100;
require(proposedPrice >= minP && proposedPrice <= maxP,
"GIVGov: price outside 7% boundary");
}
v.lastVotedPrice = proposedPrice;
v.lastVoteAt = block.timestamp;
emit PriceVoted(msg.sender, proposedPrice, block.timestamp);
}
/// @notice Tổng hợp weighted-average — ai cũng có thể gọi
function aggregateGIVPrice() external {
uint256 weightedSum = 0;
uint256 totalShares = 0;
uint256 voteCount = 0;
for (uint256 i = 0; i < validatorList.length; i++) {
Validator memory v = validators[validatorList[i]];
if (v.isActive && block.timestamp - v.lastVoteAt <= 1 days && v.lastVotedPrice > 0) {
weightedSum += v.lastVotedPrice * v.shares;
totalShares += v.shares;
voteCount++;
}
}
require(totalShares > 0, "GIVGov: no active votes in last 24h");
currentGIVPrice = weightedSum / totalShares;
emit PriceAggregated(currentGIVPrice, voteCount, block.timestamp);
}
function updateValidator(address valAddr, uint256 shares) external onlyAdmin {
bool wasActive = validators[valAddr].isActive;
bool nowActive = shares >= minShare;
validators[valAddr].shares = shares;
validators[valAddr].isActive = nowActive;
if (nowActive && !wasActive) validatorList.push(valAddr);
emit ValidatorUpdated(valAddr, shares, nowActive);
}
}
File:
contracts/EmergencyCircuitBreaker.solVai trò: Cơ chế ngắt khẩn cấp — yêu cầu bắt buộc trong thí điểm 5 năm NQ-05
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";
/**
* @title EmergencyCircuitBreaker
* @notice Cơ chế ngắt khẩn cấp theo yêu cầu Điều kiện thí điểm NQ-05/2025/NQ-CP
* @dev REGULATOR_ROLE = Bộ Tài chính / cơ quan quản lý
* OPERATOR_ROLE = Hệ thống tự động GVI (backend)
*/
contract EmergencyCircuitBreaker is AccessControl, Pausable {
bytes32 public constant REGULATOR_ROLE = keccak256("REGULATOR_ROLE");
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
mapping(address => bool) private _tokenPaused;
event GlobalPaused (address indexed by, uint256 timestamp, string reason);
event GlobalUnpaused(address indexed by, uint256 timestamp);
event TokenPaused (address indexed token, address indexed by, uint256 timestamp, string reason);
event TokenUnpaused (address indexed token, address indexed by, uint256 timestamp);
constructor(address admin, address regulator) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(REGULATOR_ROLE, regulator);
_grantRole(OPERATOR_ROLE, admin);
}
modifier tradingAllowed(address token) {
require(!paused(), "ECB: Platform globally paused");
require(!_tokenPaused[token], "ECB: Token trading suspended");
_;
}
function pauseAll(string calldata reason) external onlyRole(REGULATOR_ROLE) {
_pause();
emit GlobalPaused(msg.sender, block.timestamp, reason);
}
function unpauseAll() external onlyRole(REGULATOR_ROLE) {
_unpause();
emit GlobalUnpaused(msg.sender, block.timestamp);
}
function pauseToken(address token, string calldata reason) external {
require(hasRole(REGULATOR_ROLE, msg.sender) || hasRole(OPERATOR_ROLE, msg.sender),
"ECB: lacks permission");
_tokenPaused[token] = true;
emit TokenPaused(token, msg.sender, block.timestamp, reason);
}
function unpauseToken(address token) external {
require(hasRole(REGULATOR_ROLE, msg.sender) || hasRole(OPERATOR_ROLE, msg.sender),
"ECB: lacks permission");
_tokenPaused[token] = false;
emit TokenUnpaused(token, msg.sender, block.timestamp);
}
function isTokenPaused(address token) external view returns (bool) {
return paused() || _tokenPaused[token];
}
}
File:
contracts/InvestorWhitelist.solVai trò: Kiểm soát nhà đầu tư on-chain theo Điều 6/7 NQ-05/2025/NQ-CP
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/AccessControl.sol";
/**
* @title InvestorWhitelist
* @notice Whitelist KYC on-chain — Điều 6/7 NQ-05/2025/NQ-CP
* @dev Đồng bộ từ DB: kycApplication.status = "APPROVED" → approveInvestor()
* KYC_OPERATOR = Backend GVI (gọi sau khi eKYC pass)
* REGULATOR_ROLE = có thể revoke hàng loạt khi phát sinh vi phạm
*/
contract InvestorWhitelist is AccessControl {
bytes32 public constant KYC_OPERATOR = keccak256("KYC_OPERATOR");
bytes32 public constant REGULATOR_ROLE = keccak256("REGULATOR_ROLE");
enum InvestorType { NONE, DOMESTIC, FOREIGN }
struct Investor {
bool isWhitelisted;
InvestorType investorType;
uint8 kycLevel; // 1 | 2 | 3
uint8 amlStatus; // 0=CLEAR, 1=FLAGGED, 2=REVIEW_REQUIRED
uint256 approvedAt;
uint256 expiresAt; // Tái xác thực định kỳ
string userId; // Off-chain DB UUID
}
mapping(address => Investor) private _investors;
event InvestorApproved(address indexed wallet, InvestorType investorType,
uint8 kycLevel, string userId, uint256 expiresAt);
event InvestorRevoked(address indexed wallet, address indexed by, string reason);
event InvestorAmlFlagged(address indexed wallet, uint8 newAmlStatus);
uint256 public constant DEFAULT_VALIDITY = 365 days;
constructor(address admin) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(KYC_OPERATOR, admin);
}
function approveInvestor(
address wallet,
InvestorType investorType,
uint8 kycLevel,
string calldata userId,
uint256 validitySeconds
) external onlyRole(KYC_OPERATOR) {
require(wallet != address(0), "IW: zero address");
require(investorType != InvestorType.NONE, "IW: invalid type");
require(kycLevel >= 1 && kycLevel <= 3, "IW: kycLevel 1-3");
uint256 validity = validitySeconds > 0 ? validitySeconds : DEFAULT_VALIDITY;
uint256 expiresAt = block.timestamp + validity;
_investors[wallet] = Investor({
isWhitelisted: true,
investorType: investorType,
kycLevel: kycLevel,
amlStatus: 0,
approvedAt: block.timestamp,
expiresAt: expiresAt,
userId: userId
});
emit InvestorApproved(wallet, investorType, kycLevel, userId, expiresAt);
}
function revokeInvestor(address wallet, string calldata reason) external {
require(hasRole(KYC_OPERATOR, msg.sender) || hasRole(REGULATOR_ROLE, msg.sender),
"IW: lacks revoke permission");
_investors[wallet].isWhitelisted = false;
emit InvestorRevoked(wallet, msg.sender, reason);
}
function updateAmlStatus(address wallet, uint8 amlStatus)
external onlyRole(KYC_OPERATOR)
{
require(amlStatus <= 2, "IW: invalid AML status");
_investors[wallet].amlStatus = amlStatus;
emit InvestorAmlFlagged(wallet, amlStatus);
}
function isEligible(address wallet) external view returns (bool) {
Investor memory inv = _investors[wallet];
return inv.isWhitelisted
&& block.timestamp < inv.expiresAt
&& inv.amlStatus == 0;
}
function getInvestor(address wallet) external view returns (Investor memory) {
return _investors[wallet];
}
}
[Nhà đầu tư] → Chuyển khoản VND vào TK ngân hàng chuyên dùng GVI
↓
[Webhook NAPAS/IBFT → Backend GVI]
↓
[Oracle xác nhận → VNLToken.mintForDeposit(user, amount, bankRef)]
↓
[VNL credited → ví FIAT của user trong DB]
↓
Event: VNLMinted(user, amount, bankRef) ← on-chain evidence
[Nhà đầu tư] → Đặt lệnh mua/bán
↓
[assertTradingAllowed(symbol)] ← CircuitBreaker check
↓
[InvestorWhitelist.isEligible(wallet)] ← KYC check
↓
[Order Matching Engine khớp lệnh]
↓
[triggerTaxOnTransaction()] ← Thuế tự động Luật 71
[triggerGivUnlockOnTrade()] ← Mở khóa GIV theo volume
[walletAuditLog] ← Nhật ký bất biến
[Nhà đầu tư] → Yêu cầu rút tiền
↓
[KYC Level ≥ 2 required]
↓
[AML check: transactionMonitoring]
↓
[VNLToken.burnForWithdraw(amount)] ← Giảm total supply
↓
[Chuyển khoản VND từ TK chuyên dùng → TK ngân hàng NĐT]
↓
Event: VNLBurned(user, amount) ← on-chain evidence
| Event | Contract | Ý nghĩa pháp lý |
|---|---|---|
VNLMinted(to, amount, bankRef) |
VNLToken | Chứng từ nạp tiền — liên kết giao dịch ngân hàng |
VNLBurned(from, amount) |
VNLToken | Chứng từ rút tiền |
TokensLocked(account, amount, reason) |
GIVToken | Phong tỏa GIV theo lịch vesting |
TokensUnlocked(account, amount) |
GIVToken | Giải phóng GIV sau khi đủ điều kiện |
PriceAggregated(price, count, ts) |
GIVGovernance | Biên bản xác định giá GIV — có chữ ký validator |
InvestorApproved(wallet, type, level) |
InvestorWhitelist | Phê duyệt KYC on-chain |
InvestorRevoked(wallet, by, reason) |
InvestorWhitelist | Thu hồi quyền giao dịch |
AccountFrozen(account, status) |
VNLToken | Lệnh AML — on-chain timestamp |
GlobalPaused(by, ts, reason) |
CircuitBreaker | Ngắt khẩn cấp toàn sàn |
TokenPaused(token, by, ts, reason) |
CircuitBreaker | Tạm dừng giao dịch từng token |
Tra cứu: https://bscscan.com/tx/[hash]
pnpm compile — 0 errorsGIVToken.escrowEngine() = đúng địa chỉ backend oracleVNLToken.escrowEngine() = đúng địa chỉ backend oraclesubmitGIVPrice() vượt 7% → revert ✓mintForDeposit() trực tiếp (không qua escrow) → revert ✓freezeAccount(true) → mint revert ✓InvestorWhitelist.isEligible() trả về false với AML flagged ✓EmergencyCircuitBreaker.pauseAll() → mọi lệnh bị reject ✓aggregateGIVPrice()alphaRate được Ban Quản trị phê duyệt bằng biên bản họpowner/admin sang Gnosis Safe Multisig (tối thiểu 3/5).env sau khi deploy# BSC Smart Contracts — GVI Network
GIV_CONTRACT_BSC=0x_______________
VNL_TOKEN_CONTRACT_BSC=0x_______________
GIV_GOV_CONTRACT_BSC=0x_______________
CIRCUIT_BREAKER_CONTRACT=0x_______________
INVESTOR_WHITELIST_CONTRACT=0x_______________
# Backend config
CIRCUIT_BREAKER_SIGNER_KEY=0x_______________ # OPERATOR_ROLE private key
GIV_UNLOCK_ALPHA=0.0005 # 0.05% per VNL volume
MAX_CONCURRENT_SESSIONS=5
| Tài liệu | Đường dẫn |
|---|---|
| Kiến trúc hệ thống đầy đủ | docs/newproject001.md |
| Đề án kỹ thuật chi tiết | docs/GVI-NETWORK-TECHNICAL-PROPOSAL.md |
| GVI contracts source | backend/ecosystem/smart-contracts/gvi/ |
| Tax Engine | backend/src/tax/taxCalculatorEngine.ts |
| Circuit Breaker Service | backend/src/security/circuitBreakerService.ts |
| Session Guard | backend/src/security/sessionGuard.ts |
| Migration SQL | backend/scripts/migration-tax-circuit-breaker.sql |
| BSCScan Mainnet | https://bscscan.com |
| BSCScan Testnet | https://testnet.bscscan.com |
| Remix IDE | https://remix.ethereum.org |
| Gnosis Safe | https://safe.global |
Tài liệu kỹ thuật nội bộ v3.0.0 — GoldVN Invest (GVI Network) GCNĐKDN số 0111319828 — Phòng ĐKKD & TCDN Hà Nội cấp ngày 19/12/2025 Mọi thay đổi phải được phê duyệt bởi Ban Quản Trị GVI và lưu vào git commit có GPG signature.