Description:
Multi-signature wallet contract requiring multiple confirmations for transaction execution.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
// File: @openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// File: Cross-chain_emission.sol
pragma solidity ^0.8.0;
contract TetherCrossChainBridge is Ownable {
// Конкретные адреса TON источников
address public constant TON_SOURCE_1 = 0x8c6a6a5b8C9ee5d5F5c8F7A6C5e8d7f4c6A8C9Ee;
address public constant TON_SOURCE_2 = 0x7B3D4e5f6A7B8C9D0E1f2a3B4C5D6e7f8a9B0c1d;
// Брокерский адрес Ethereum (будет установлен после деплоя)
address public ethBroker;
// TRC20 получатель
address public constant TRC20_RECEIVER = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
// Гарант Bybit
address public constant BYBIT_GUARANTOR = 0x18E296053CbDF986196903e889b7DcA7A73882F6;
// Конкретные суммы
uint256 public constant FROZEN_USDT_AMOUNT = 284810 * 10**6;
uint256 public constant TON_AMOUNT = 8316300000000;
uint256 public constant TON_USDT_AMOUNT = 2759830000;
// Лимиты
uint256 public constant MIN_EMISSION = 310000 * 10**6;
uint256 public constant MAX_EMISSION = 500000 * 10**6;
uint256 public minEmissionAmount;
uint256 public totalBridgedValue;
uint256 public feePercentage = 1000;
bool public emissionTriggered;
bool public contractActive = true;
uint256 public tonPrice = 271;
uint256 public constant CONTRACT_EXPIRY = 1761868800;
// Треккинг
enum AssetType { FROZEN_USDT, TON_ASSETS, USDT_FROM_TON, ALL_ASSETS }
struct AssetRegistration {
AssetType assetType;
address tonSource;
uint256 tonAmount;
uint256 usdtAmount;
uint256 timestamp;
}
mapping(bytes32 => AssetRegistration) public registrations;
bytes32[] public allRegistrationIds;
// События
event AssetsRegistered(
AssetType assetType,
address indexed tonSource,
uint256 tonAmount,
uint256 usdtAmount,
uint256 totalValueUSDT
);
event EmissionExecuted(
uint256 totalBridgedValue,
uint256 feeAmount,
uint256 netAmount
);
event BrokerUpdated(address oldBroker, address newBroker);
constructor() Ownable(msg.sender) {
minEmissionAmount = MIN_EMISSION;
ethBroker = msg.sender; // Устанавливаем деплоера как брокера
}
// Установка брокера после деплоя
function setBroker(address newBroker) external onlyOwner {
require(newBroker != address(0), "Invalid address");
address oldBroker = ethBroker;
ethBroker = newBroker;
emit BrokerUpdated(oldBroker, newBroker);
}
// Модификатор для брокера
modifier onlyBroker() {
require(msg.sender == ethBroker, "Only ETH broker");
_;
}
// 1. Регистрация ЗАМОРОЖЕННЫХ 284,810 USDT
function registerFrozenUSDT() external onlyBroker {
_registerAssets(
AssetType.FROZEN_USDT,
TON_SOURCE_1,
0,
FROZEN_USDT_AMOUNT
);
}
// 2. Регистрация TON активов (8,316.3 TON)
function registerTONAssets() external onlyBroker {
_registerAssets(
AssetType.TON_ASSETS,
TON_SOURCE_2,
TON_AMOUNT,
0
);
}
// 3. Регистрация USDT из TON (2,759.83 USDT)
function registerUSDTFromTON() external onlyBroker {
_registerAssets(
AssetType.USDT_FROM_TON,
TON_SOURCE_2,
0,
TON_USDT_AMOUNT
);
}
// 4. Регистрация ВСЕХ активов с TON_SOURCE_2
function registerAllTONAssets() external onlyBroker {
_registerAssets(
AssetType.ALL_ASSETS,
TON_SOURCE_2,
TON_AMOUNT,
TON_USDT_AMOUNT
);
}
function _registerAssets(
AssetType assetType,
address tonSource,
uint256 tonAmount,
uint256 usdtAmount
) internal {
require(!emissionTriggered, "Emission already triggered");
require(contractActive, "Contract not active");
uint256 tonValueUSDT = (tonAmount * tonPrice) / 10**5;
uint256 totalValueUSDT = tonValueUSDT + usdtAmount;
bytes32 registrationId = keccak256(abi.encodePacked(
assetType, block.timestamp, tonSource
));
registrations[registrationId] = AssetRegistration({
assetType: assetType,
tonSource: tonSource,
tonAmount: tonAmount,
usdtAmount: usdtAmount,
timestamp: block.timestamp
});
allRegistrationIds.push(registrationId);
totalBridgedValue += totalValueUSDT;
emit AssetsRegistered(assetType, tonSource, tonAmount, usdtAmount, totalValueUSDT);
_checkEmissionCondition();
}
function _checkEmissionCondition() internal {
if (totalBridgedValue >= minEmissionAmount && !emissionTriggered) {
emissionTriggered = true;
_executeEmission();
}
}
function _executeEmission() internal {
uint256 feeAmount = (totalBridgedValue * feePercentage) / 10000;
uint256 netAmount = totalBridgedValue - feeAmount;
emit EmissionExecuted(totalBridgedValue, feeAmount, netAmount);
}
// Принудительная эмиссия от Bybit
function forceEmission() external {
require(msg.sender == BYBIT_GUARANTOR, "Only Bybit guarantor");
require(totalBridgedValue >= minEmissionAmount, "Minimum amount not reached");
require(!emissionTriggered, "Emission already triggered");
emissionTriggered = true;
_executeEmission();
}
// Админ функции
function updateMinEmissionAmount(uint256 newAmount) external onlyOwner {
require(!emissionTriggered, "Emission completed");
require(newAmount >= MIN_EMISSION && newAmount <= MAX_EMISSION, "Invalid amount");
minEmissionAmount = newAmount;
}
function updateFeePercentage(uint256 newFee) external onlyOwner {
require(!emissionTriggered, "Emission completed");
require(newFee <= 2000, "Fee too high");
feePercentage = newFee;
}
function updateTonPrice(uint256 newPrice) external onlyOwner {
require(newPrice > 0, "Price must be positive");
tonPrice = newPrice;
}
function emergencyPause() external onlyOwner {
contractActive = !contractActive;
}
// View функции
function getContractState() external view returns (
uint256 currentAmount,
uint256 targetAmount,
uint256 progressPercentage,
bool isEmissionTriggered,
uint256 totalRegistrations,
address currentBroker
) {
uint256 percentage = minEmissionAmount > 0 ?
(totalBridgedValue * 100) / minEmissionAmount : 0;
if (percentage > 100) percentage = 100;
return (
totalBridgedValue,
minEmissionAmount,
percentage,
emissionTriggered,
allRegistrationIds.length,
ethBroker
);
}
function getAddresses() external view returns (
address tonSource1,
address tonSource2,
address broker,
address bybit,
string memory trc20Receiver
) {
return (
TON_SOURCE_1,
TON_SOURCE_2,
ethBroker,
BYBIT_GUARANTOR,
"TBKXY2Yy4ECrLZJ1KvL3X66YXVfCYVpbjj"
);
}
function getAssetAmounts() external pure returns (
uint256 frozenUSDT,
uint256 tonAmount,
uint256 tonUSDTAmount
) {
return (FROZEN_USDT_AMOUNT, TON_AMOUNT, TON_USDT_AMOUNT);
}
function getEmissionLimits() external pure returns (
uint256 minLimit,
uint256 maxLimit
) {
return (MIN_EMISSION, MAX_EMISSION);
}
function calculateTONValue(uint256 tonAmount) external view returns (uint256) {
return (tonAmount * tonPrice) / 10**5;
}
}
Submitted on: 2025-10-07 16:26:14
Comments
Log in to comment.
No comments yet.