Description:
Smart contract deployed on Ethereum with Factory features.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"contracts/SimpleDepositVault.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title StakingContract (Remix-ready)
/// @notice 사용자: deposit/withdraw 가능, 관리자: withdrawAll 가능
/// @dev ReentrancyGuard 내장, CEI 순서 준수, 직접 송금 금지로 회계 일치 유지
contract StakingContract {
// --- admin & pause ---
address public immutable admin; // 배포 시 고정
bool public paused;
// --- accounting ---
uint256 public totalDeposits;
mapping(address => uint256) public userBalances;
// --- events ---
event Deposit(address indexed user, uint256 amount);
event Withdraw(address indexed user, uint256 amount);
event AdminWithdrawal(address indexed admin, uint256 amount);
event Paused(bool paused);
// --- reentrancy guard (최소 구현) ---
uint256 private _locked = 1;
modifier nonReentrant() {
require(_locked == 1, "REENTRANCY");
_locked = 2;
_;
_locked = 1;
}
modifier onlyAdmin() {
require(msg.sender == admin, "not admin");
_;
}
modifier whenNotPaused() {
require(!paused, "paused");
_;
}
constructor(address _admin) {
require(_admin != address(0), "zero admin");
admin = _admin;
}
// 직접 송금은 막아 deposit()만 사용하도록 강제 (회계 일치)
receive() external payable { revert("use deposit()"); }
fallback() external payable { revert("use deposit()"); }
// --- admin controls ---
function setPaused(bool _p) external onlyAdmin {
paused = _p;
emit Paused(_p);
}
// --- user flows ---
function deposit() external payable whenNotPaused nonReentrant {
require(msg.value > 0, "zero amount");
userBalances[msg.sender] += msg.value;
totalDeposits += msg.value;
emit Deposit(msg.sender, msg.value);
}
function withdraw(uint256 amount) external nonReentrant {
require(amount > 0, "zero amount");
uint256 bal = userBalances[msg.sender];
require(amount <= bal, "insufficient");
// CEI: 상태 업데이트 먼저
userBalances[msg.sender] = bal - amount;
totalDeposits -= amount;
// 안전 전송 (transfer 대신 call)
(bool ok, ) = payable(msg.sender).call{value: amount}("");
require(ok, "ETH send failed");
emit Withdraw(msg.sender, amount);
}
// --- admin withdraw all ---
function withdrawAll(address payable to) external onlyAdmin nonReentrant {
require(to != address(0), "zero to");
uint256 amt = address(this).balance;
require(amt > 0, "empty");
// 운영 중단 후 회수(권장 플로우)
if (!paused) {
paused = true;
emit Paused(true);
}
(bool ok, ) = to.call{value: amt}("");
require(ok, "ETH send failed");
emit AdminWithdrawal(admin, amt);
// 주의: 장부(userBalances/totalDeposits)는 남습니다.
// 실자산은 빠져나가므로 이후 사용자 withdraw는 실패합니다.
// 의도된 청산 시점에서만 호출하세요.
}
// 편의 조회
function contractBalance() external view returns (uint256) {
return address(this).balance;
}
}
"
}
},
"settings": {
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}
}}
Submitted on: 2025-11-01 11:18:10
Comments
Log in to comment.
No comments yet.