Skip to content

Summersurf0452/week 03#57

Open
summersurf0452 wants to merge 2 commits intoBay-17th:mainfrom
summersurf0452:summersurf0452/week-03
Open

Summersurf0452/week 03#57
summersurf0452 wants to merge 2 commits intoBay-17th:mainfrom
summersurf0452:summersurf0452/week-03

Conversation

@summersurf0452
Copy link

과제 제출 정보

주차: Week 03

과제 유형:

  • 이론 (Theory Quiz)
  • 개발 (Dev Assignment)

구현 내용

  • VaultSecure.sol: CEI 패턴 + 재진입 잠금(bool _locked)으로 안전한 deposit/withdraw 를 구현하였습니다
  • CEI 패턴을 사용해 코드 순서를 안전하게 배치하고, nonReentrant modifier로 재진입 자체를 명시적으로 차단하는 이중 방어를 적용하였습니다
  • quiz-03-solution.md에서 EVM 결정론, Storage/Memory/Stack 비용, CEI, tx.origin 취약점, ReentrancyGuard 비교, 재진입 다이어그램 해석 문제를 정리했습니다.

배운 점 (What I Learned)

이번 주에 배운 것 (2-3가지)

  1. 외부 호출 중에 상태가 아직 변경되지 않았으면 같은 함수를 반복 호출해서 자금을 탈취할 수 있다는 재진입 공격의 원리를 새로 알게되었습니다
  2. CEI 패턴에 대해 알게되었습니다. Checks → Effects → Interactions 순서로 상태를 먼저 변경하고 외부 호출을 마지막에 하면 재진입을 방어할 수 있다는 것을 배웠습니다.
  3. CEI 패턴은 설계 원칙이고, ReentrancyGuard는 실행 시점 잠금 장치라는 차이를 배웠습니다.
  4. 퀴즈를 통해 권한 검증에서 tx.origin 대신 msg.sender를 사용해야 피싱 공격에 안전하다는 것을 배웠습니다.

어려웠던 점과 해결 방법

어려웠던 점:

초기에 CEI 패턴만 적용해 withdraw()를 구현했을 때, 재진입 시 내부 호출에서 발생한 revert가 공격자 receive()를 거쳐 바깥 call까지 전파되었습니다.
그 결과 successfalse가 되어 "Transfer failed"로 정상 출금도 함께 취소되는 일이 벌어졌습니다.
silent return 방식(if (_locked) return;)을 사용하면 된다는 것을 배웠지만, 실무에서 널리 권장되는 패턴은 아니라고 하여 실무에서 자주 쓰이는 방법으로 다시 구현하였습니다

해결 방법:

최종적으로 업계 표준인 nonReentrant modifier명시적 revert를 채택했습니다.
재진입 시도를 require(!_locked, "ReentrancyGuard: reentrant call")로 명확히 차단하는 방식이며, OpenZeppelin ReentrancyGuard와 동일한 접근입니다.
현재 테스트의 Attacker 컨트랙트는 revert를 상위 호출로 전파하는 구조라 일부 재진입 테스트와 충돌이 있었지만, 보안 관점에서 재진입 자체는 확실히 차단되므로 이 구현을 최종 선택했습니다.

처음에는 if (_locked) return;처럼 조용히 넘기는 방식을 써봤는데, 실무에서 표준적으로 많이 쓰는 방식이 아니라고 하여 대신 OpenZeppelin에서 쓰는 방식처럼 nonReentrant를 사용해서 명시적 revert로 재진입을 막는 방향으로 다시 구현하였습니다
테스트 일부와 충돌하는 부분은 있었지만, 보안 관점에서는 재진입 자체를 명확하게 차단하는 게 더 중요하다고 판단해서 이 구현을 선택하였습니다.

질문 사항

-nonReentrant(revert)를 쓰면 공격자가 자기 돈을 못 돌려받고, silent return을 쓰면 자기 돈은 돌려받는데, 어떤 쪽으로 구현하는게 올바른 방향인가요.??


체크리스트

테스트

  • forge build 성공
  • forge test 모든 테스트 통과->VaultSecure 10/12 통과

제출 규칙

  • 브랜치명이 {username}/week-{XX} 형식
  • .env 파일이 커밋에 포함되지 않음
  • 커밋 메시지가 규칙을 따름

@summersurf0452 summersurf0452 force-pushed the summersurf0452/week-03 branch from 500e363 to 032c95d Compare March 7, 2026 01:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant