diff --git a/problemVersion1/1/problem1.txt b/problemVersion1/1/problem1.txt index 6a53544..f36b9a7 100644 --- a/problemVersion1/1/problem1.txt +++ b/problemVersion1/1/problem1.txt @@ -1,9 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -// Declare public state variables as command, then assign the default value of that type. +// Declare public state variables, then assign the default value of that type. +// In fact you do not to assign the default value cuz it's "default" contract answer1 { - // TODO: declare a uint variable named myUint + // TODO: declare a uint256 variable named myUint // TODO: declare a boolean variable named myBool @@ -12,7 +13,11 @@ contract answer1 { // TODO: declare a string variable named myString - function getUint() public view returns (uint) { + + + // --------------Below are judging functions------------------- + + function getUint() public view returns (uint256) { return myUint; } function getBool() public view returns (bool) { diff --git a/problemVersion1/10/problem10.txt b/problemVersion1/10/problem10.txt index edda84d..5ccbcfd 100644 --- a/problemVersion1/10/problem10.txt +++ b/problemVersion1/10/problem10.txt @@ -1,7 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; + // The system will deploy `Called` for you +// The interface you are going to write will be use to call contract `Called`. contract Called { bool public called = false; @@ -13,7 +15,9 @@ contract Called { } } -// TODO: write an interface named `ICalled`, implement the two functions in contract `Called`. +// TODO 1: write an interface named `ICalled`, implement the two functions which is in contract `Called`. + + contract answer10 { @@ -24,10 +28,14 @@ contract answer10 { } function setCalled() external { - // TODO: finish this function by using `ICalled` to call `setCalled()` in contract `Called`. + // TODO 2: Finish this function by using `ICalled` to call `setCalled()` in contract `Called`. + } + + // --------------Below are judging functions------------------- + function checkAns() external view returns (bool) { return ICalled(address(calledContract)).getCalled(); } diff --git a/problemVersion1/11/problem11.txt b/problemVersion1/11/problem11.txt index 3e9274b..ab6bb55 100644 --- a/problemVersion1/11/problem11.txt +++ b/problemVersion1/11/problem11.txt @@ -23,12 +23,16 @@ contract answer11 { called = new Called(); } - // TODO: Declare a function named `sendETHtoCalled`. + // TODO 1: Declare a function named `sendETHtoCalled`. + + // This function should send 50000 wei to the contract `called` using method `call` // Assign the first return value to `success`. // Notice that there are multiple return values of method call. + // --------------Below are judging functions------------------- + function checkAns() external view returns(uint256) { require(success, "transfer not success"); return called.getBalance(); diff --git a/problemVersion1/12/problem12.txt b/problemVersion1/12/problem12.txt index 6fea115..54bcd79 100644 --- a/problemVersion1/12/problem12.txt +++ b/problemVersion1/12/problem12.txt @@ -17,17 +17,24 @@ contract answer12 { Called public called; bool public success; + + + // TODO: write a function named `callSetGreet()`, take a string as a param. + + + + // This function should call function `setGreet()` in contract `called` and a string as param. + // You can, but not required, send some ETH with this call . + + + + // --------------Below are judging functions------------------- + receive() external payable {} function deployContract() external { called = new Called(); } - - // TODO: write a function named `callSetGreet()`, taking a string as a parameter. - // This function should call function `setGreet()` in contract `called` and input the param string. - // You can, but not required, send some ETH with this call . - - function getGreet() external view returns (string memory) { return called.getGreet(); } diff --git a/problemVersion1/13/problem13.txt b/problemVersion1/13/problem13.txt index 89d208d..0fa2b9d 100644 --- a/problemVersion1/13/problem13.txt +++ b/problemVersion1/13/problem13.txt @@ -2,15 +2,20 @@ pragma solidity ^0.8.17; contract answer13 { - // TODO: Define a struct named `Food`, - // The first variable is a string named `name`, and the second is a uint256 named `price`. + // TODO 1: Define a struct named `Food`, + // This struct includes a string named `name`, and a uint256 named `price`. - // TODO: Declare a Food array named `foods` - // TODO: Declare a function named `createFood()`, it should let user createNewFood. - // That is, it should take a string and a uint256 as param, create a `Food`, and push it into the array `foods`. + // TODO 2: Declare a Food array named `foods` + // TODO 3: Declare a function named `createFood()` + // It should take a string and a uint256 as param, create a `Food`, and push it into the array `foods`. + + + + // --------------Below are judging functions------------------- + function checkAns() external view returns (string memory, uint256) { return (foods[0].name, foods[0].price); } diff --git a/problemVersion1/16/problem16.txt b/problemVersion1/16/problem16.txt index 0b5fd73..4a9221b 100644 --- a/problemVersion1/16/problem16.txt +++ b/problemVersion1/16/problem16.txt @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; +// In this problem, we are going to write our ERC20 contract ! + interface IERC20 { event Transfer(address indexed from, address indexed to, uint256 value); @@ -12,7 +14,7 @@ interface IERC20 { function transfer(address to, uint256 amount) external returns (bool); - // The functions below are commented for judging/compiling reasons. + // ---------functions below are commented for compiling reasons.-------- // function allowance(address owner, address spender) external view returns (uint256); // function approve(address spender, uint256 amount) external returns (bool); @@ -20,7 +22,7 @@ interface IERC20 { // function transferFrom(address from, address to, uint256 amount) external returns (bool); } -// Finish the functions below, you can have a peek to the interface if you feel it difficult. +// Finish the functions below, you can take a look at the interface if you find it difficult. contract answer16 is IERC20 { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; @@ -34,10 +36,13 @@ contract answer16 is IERC20 { // Finish the `totalSupply` function, it should return the totalSupply of this ERC20 token. + // Finish the `balanceOf` function, it should return the balance of an input address. + // Finish the `transfer` function, it should transfer specific amount of ETH from the function called to another address and return true. + } diff --git a/problemVersion1/17/problem17.txt b/problemVersion1/17/problem17.txt index 39a4122..62e2e6b 100644 --- a/problemVersion1/17/problem17.txt +++ b/problemVersion1/17/problem17.txt @@ -2,7 +2,8 @@ pragma solidity ^0.8.17; // Cont'd -// Finish the ERC20 +// If you haven't done the part 1, it is recommended first +// Finish the ERC20 contract interface IERC20 { event Transfer(address indexed from, address indexed to, uint256 value); @@ -49,7 +50,8 @@ contract answer17 is IERC20 { //========= All the Todos are below here ========== - // TODO: Finish the function `allowance`, it should return the allowance from owner to spender. + // TODO 1: Finish the function `allowance`, it should return the allowance from owner to spender. + @@ -63,19 +65,21 @@ contract answer17 is IERC20 { require(_owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); - // TODO: set the allowance from `owner` to `sender` to be `amount` + // TODO 2: set the allowance from `owner` to `sender` to be `amount` - // TODO: fire the event `Approval` + // TODO 3: fire the event `Approval` } - // TODO: Finish function `transferFrom` + // TODO 4: Finish function `transferFrom` // It should call `_spendAllowance()` and `_transfer()`, try to pass in the correct param ! - // ========== All todos are done ! Good job ======= + + + // --------------Below are judging functions------------------- function _spendAllowance(address _owner, address spender, uint256 amount) internal virtual { uint256 currentAllowance = _allowances[owner][spender]; diff --git a/problemVersion1/18/answer18.sol b/problemVersion1/18/answer18.sol index 8ae34a9..a7fa2b8 100644 --- a/problemVersion1/18/answer18.sol +++ b/problemVersion1/18/answer18.sol @@ -22,10 +22,6 @@ contract answer18 is IERC165, IAnother { function aFunction() external returns (bool) {} function bFunction() external returns (bool) {} - - function getIAnotherId() external pure returns(bytes4) { - return this.aFunction.selector ^ this.bFunction.selector; - } } diff --git a/problemVersion1/18/problem18.txt b/problemVersion1/18/problem18.txt index c0b19b1..0e45d7e 100644 --- a/problemVersion1/18/problem18.txt +++ b/problemVersion1/18/problem18.txt @@ -7,19 +7,20 @@ interface IERC165 { } interface IAnother { - function aFunction() external returns (bool); - function bFunction() external returns (bool); + function aFunction() external returns (bool); + function bFunction() external returns (bool); } contract answer18 is IERC165, IAnother { - // TODO: write a function named `supportsInterface` which takes a bytes4 as an input. - // This function check if the input interfaceID is supported by this contract. - // Note that `answer18` contract supports two interface: IERC165 and IAnother. + // TODO: write a function named `supportsInterface` which takes a bytes4 as an input. + // This function check if the input interfaceID is supported by this contract. + // Note that `answer18` contract supports two interface: IERC165 and IAnother. + function aFunction() external returns (bool) {} function bFunction() external returns (bool) {} } diff --git a/problemVersion1/19/problem19.txt b/problemVersion1/19/problem19.txt index 05e119f..a741d88 100644 --- a/problemVersion1/19/problem19.txt +++ b/problemVersion1/19/problem19.txt @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; +// ERC721! We are going to write our own ERC721 contract. interface IERC165 { function supportsInterface(bytes4 interfaceID) external view returns (bool); } @@ -26,17 +27,17 @@ contract ERC721 is IERC721 { interfaceId == type(IERC165).interfaceId; } - // TODO: write a `_mint` internal function taking an address and an id + // TODO 1: write a `_mint` internal function taking an address and an id // It should revert with "mint to zero address" message if so // It should revert with "already minted" message if so // it should emit Transfer - // TODO: write an `ownerOf` external function. + // TODO 2: write a `ownerOf` external function. // It should revert with "token doesn't exist" if so - // TODO: write an `balanceOf` external function. + // TODO 3: write a `balanceOf` external function. // It should revert with "owner = zero address" if someone query for zero address @@ -48,6 +49,6 @@ contract answer19 is ERC721 { function mint(address to, uint256 id) external { _mint(to, id); } - + } diff --git a/problemVersion1/2/problem2.txt b/problemVersion1/2/problem2.txt index 2777f14..a2e517e 100644 --- a/problemVersion1/2/problem2.txt +++ b/problemVersion1/2/problem2.txt @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -// Below you have to declare public functions, remember to assign the type of functions( pure or view ) +// Declare public functions, remember to assign the type of functions, that is, pure or view. contract answer2 { uint public x = 1; diff --git a/problemVersion1/20/problem20.txt b/problemVersion1/20/problem20.txt index e4a2b51..34fd9a8 100644 --- a/problemVersion1/20/problem20.txt +++ b/problemVersion1/20/problem20.txt @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; +// Cont'd +// If you haven't done part 1, it is recommended to do it first. interface IERC165 { function supportsInterface(bytes4 interfaceID) external view returns (bool); } @@ -88,19 +90,21 @@ contract ERC721 is IERC721 { spender == _approvals[id]); } - // write a function named `transferFrom` + // TODO 1: write a function named `transferFrom` // it should transfer token if all requirement are satisfied // it should revert with "transfer to zero address" message if so // it should fire event `Transfer` - // write a function named `_burn` taking one uint256 as param + // TODO 2: write a function named `_burn` taking one uint256 as param // It should burn token // it should revert with "not minted" if so // it should emit `Transfer` as it transfer token to zero address + + } contract answer20 is ERC721 { diff --git a/problemVersion1/3/problem3.txt b/problemVersion1/3/problem3.txt index 4126691..0a8d651 100644 --- a/problemVersion1/3/problem3.txt +++ b/problemVersion1/3/problem3.txt @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -// complete the function below +// Complete the function below. contract answer3 { function biggerThanTen(uint256 num) public pure returns (bool) { - // if the input is bigger than ten, return true, else return false + // If the input is bigger than ten, return true, else return false } } \ No newline at end of file diff --git a/problemVersion1/4/answer4.sol b/problemVersion1/4/answer4.sol index 6baf26c..7ce115e 100644 --- a/problemVersion1/4/answer4.sol +++ b/problemVersion1/4/answer4.sol @@ -2,14 +2,14 @@ pragma solidity ^0.8.17; contract answer4 { mapping(address => uint256) balanceOf; - mapping(address => mapping(uint256 => bool)) AddressOwnNum; + mapping(address => mapping(uint256 => bool)) addressOwnNum; function setBalanceOf(address _user, uint256 _balance) public { balanceOf[_user] = _balance; } function setAddressOwnNFT(address _user, uint256 _num) public { - AddressOwnNum[_user][_num] = true; + addressOwnNum[_user][_num] = true; } function getBalanceOf(address _user) public view returns (uint256) { @@ -17,6 +17,6 @@ contract answer4 { } function getAddressOwnNum(address _user, uint256 _num) public view returns (bool) { - return AddressOwnNum[_user][_num]; + return addressOwnNum[_user][_num]; } } \ No newline at end of file diff --git a/problemVersion1/4/problem4.txt b/problemVersion1/4/problem4.txt index a7077bf..1a125ec 100644 --- a/problemVersion1/4/problem4.txt +++ b/problemVersion1/4/problem4.txt @@ -1,13 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; +// We want to record that how much token does an address own. contract answer4 { - // imagine we can record that an address own how much token - // TODO: declare a mapping mapping from an address to an uint256 named `balanceOf` + // TODO: declare a mapping, mapping from an address to an uint256 named `balanceOf` - // imagine we can record that whether an address owns a NFT with a serial number - // TODO: declare a nested mapping mapping from an address to a mapping which maps from a uint256 to a boolean named `AddressOwnNFT` + + // TODO: declare a nested mapping, mapping from an address to a mapping, which, maps from a uint256 to a boolean named `addressOwnNFT` + function setBalanceOf(address _user, uint256 _balance) public { // TODO: set the balanceOf _user to _balance @@ -18,11 +19,13 @@ contract answer4 { } + + // --------------Below are judging functions------------------- function getBalanceOf(address _user) public view returns (uint256) { return balanceOf[_user]; } function getAddressOwnNum(address _user, uint256 _num) public view returns (bool) { - return AddressOwnNum[_user][_num]; + return addressOwnNum[_user][_num]; } } \ No newline at end of file diff --git a/problemVersion1/5/problem5.txt b/problemVersion1/5/problem5.txt index 0cbb288..7f198a5 100644 --- a/problemVersion1/5/problem5.txt +++ b/problemVersion1/5/problem5.txt @@ -9,9 +9,12 @@ contract answer5 { // TODO: declare a function modifier named `onlyOwner` which restrict that only the owner can call the modified function. + // TODO: declare a function named `changeOwner` which takes an address as an input, this function assigns the input address to `owner`. Don't forget to use the modifier `onlyOwner` to restrict the caller of this function. + // --------------Below are judging functions------------------- + function getowner() external view returns (address) { return owner; } diff --git a/problemVersion1/50/answer50.sol b/problemVersion1/50/answer50.sol index 6dc2b64..285268f 100644 --- a/problemVersion1/50/answer50.sol +++ b/problemVersion1/50/answer50.sol @@ -47,7 +47,7 @@ contract answer50 { } function withdraw() external { - require(msg.sender == winner, "Highest bidder cannot withdraw."); + require(msg.sender != winner, "Highest bidder cannot withdraw."); uint256 bal = bids[msg.sender]; bids[msg.sender] = 0; diff --git a/problemVersion1/50/problem50.txt b/problemVersion1/50/problem50.txt index e0a8d50..dedb18d 100644 --- a/problemVersion1/50/problem50.txt +++ b/problemVersion1/50/problem50.txt @@ -1,6 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; +// Ref: https://solidity-by-example.org/app/english-auction/ + +// This is an English auction contract! +// An English Auction, also referred to as an open cry ascending auction, starts by an auctioneer announcing the suggested opening bid or reserve price for the item on sale. The buyers with interest in the item start placing bids on the item on sale, with the auctioneer accepting higher bids as they come. contract answer50 { event Start(); event Bid(address indexed bidder, uint256 amount); @@ -22,13 +26,13 @@ contract answer50 { } function start() external { - //TODO 1: require not started and revert with "started", + //TODO 1: require not started and revert with error "started", // require that only `seller` can call start started = true; nowTime = 0; - // This is only for judgement, in real case you have to use `block.timestamp` + // This is only for judgement, we mock the time using `nowTime`, in real case you have to use `block.timestamp` endTime = nowTime + 10; emit Start(); @@ -40,7 +44,8 @@ contract answer50 { // TODO 2: declare an uint256 named `newBid` and calculate a bidders new bid with msg.value. // You should check if the new bid is biger that the current winner, - // if not, revert with message "lower than the highest bid."" + // if not, revert with message "lower than the highest bid. + // TODO 3: if all requirement are satisfied, modify `winner`, `highestBid` and `bids`, last emit `Bid` @@ -65,7 +70,9 @@ contract answer50 { } - // DO NOT modify functions below, these are for judgements. + + //-------- Below are judging functions ------------ + function setTimeToEnd() external { nowTime = endTime; } diff --git a/problemVersion1/51/problem51.txt b/problemVersion1/51/problem51.txt index 5816a29..32b2525 100644 --- a/problemVersion1/51/problem51.txt +++ b/problemVersion1/51/problem51.txt @@ -1,9 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -// Dutch Auction introduction: A Dutch auction is a type of auction where the auctioneer begins with a high asking price for the item being sold and gradually lowers the price until a bidder accepts the current price. The first bidder to accept the current price wins the auction and pays the final price. +// Dutch Auction introduction: +// A Dutch auction is a type of auction where the auctioneer begins with a high asking price for the item being sold and gradually lowers the price until a bidder accepts the current price. The first bidder to accept the current price wins the auction and pays the final price. -//TODO: complete this dutch auction +//TODO: complete this dutch auction contract contract answer51 { uint private constant DURATION = 15; @@ -14,7 +15,7 @@ contract answer51 { uint public immutable discountRate; bool public ended = false; - // mock of block.timestamp + // this is a mock of block.timestamp uint256 public nowTime = 1677679389; @@ -30,7 +31,7 @@ contract answer51 { } function getPrice() public view returns (uint) { - //TODO 2: calculate the price and return it + //TODO 2: calculate the current price and return it. } @@ -49,7 +50,10 @@ contract answer51 { ended = true; } - //functions for judging + + + //-------- Below are judging functions ------------ + function addNowTime(uint256 addTime) external { nowTime += addTime; } diff --git a/problemVersion1/52/problem52.txt b/problemVersion1/52/problem52.txt index c885f61..bf10936 100644 --- a/problemVersion1/52/problem52.txt +++ b/problemVersion1/52/problem52.txt @@ -1,13 +1,16 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +// Ref: https://github.com/harendra-shakya/smart-contract-attack-vectors/blob/main/attack-vectors/Reentrancy.md + // This is a vulnerable contract // We have a contract named problem52 which can steal ethers from this contract by calling `attack`. // modify VulnerableContract to prevent reentrancy from happening. contract VulnerableContract { mapping (address => uint) public balances; - //TODO: modify for preventing reentrancy + // TODO: modify for preventing reentrancy + // hint: write a modifier and use it for functions needed diff --git a/problemVersion1/53/problem53.txt b/problemVersion1/53/problem53.txt index c79e7f3..0cb1379 100644 --- a/problemVersion1/53/problem53.txt +++ b/problemVersion1/53/problem53.txt @@ -1,8 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -//This is multiCall, we want to write a function which can execute multiple calls where user inputs there call datas. - +// This is multiCall, we want to write a function which can execute multiple calls in one transaction. contract Test { function test1() external pure returns (uint256) { @@ -26,7 +25,7 @@ contract answer53 { address[] public targets = new address[](2); // For judge system reasons, - // we pretent that users inputs `datas` as calldata, and `targets` as targets address, their owns. + // we pretent that users inputs `datas` as calldata, and `targets` as targets address, they are both arrays. function multiCall() external view returns (bytes[] memory) { require(datas.length == targets.length, "Length not equal"); bytes[] memory results = new bytes[](datas.length); @@ -34,11 +33,14 @@ contract answer53 { // TODO: execute the calldatas from the address, for this problem, the call amount is specified as 2. // Store the results in `results`. + + return results; } + // ------- Below are judging functions------------- function deployTest() external { testContract = new Test(); diff --git a/problemVersion1/54/problem54.txt b/problemVersion1/54/problem54.sol similarity index 80% rename from problemVersion1/54/problem54.txt rename to problemVersion1/54/problem54.sol index ad9042b..a243078 100644 --- a/problemVersion1/54/problem54.txt +++ b/problemVersion1/54/problem54.sol @@ -6,14 +6,24 @@ contract answer54 { bytes[] public answers = new bytes[](2); //TODO: Write a function named `delegateCall` taking a bytes calldata array. - // This bytes array will be inputs like ["0x6b59084d", "0x66e41cb7"] as function selectors. + // This bytes array will be input like + // ["0x6b59084d", "0x66e41cb7"] + // as function selectors. // You shoud delegateCall each functions inputed, and record the reply from `delegatecall` in `answers`. + + + + // In fact, ["0x6b59084d", "0x66e41cb7"] is the selector of test1 and test2 below. It will be the test sample. + + + // ------- Below are judging functions------------- + function test1() external returns (uint256) { emit Log(msg.sender); return 1; diff --git a/problemVersion1/55/answer55.sol b/problemVersion1/55/answer55.sol index 20697d0..9b91743 100644 --- a/problemVersion1/55/answer55.sol +++ b/problemVersion1/55/answer55.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; + + contract answer55 { bytes32 answer; @@ -11,7 +13,7 @@ contract answer55 { keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes("answer55")), keccak256(bytes("1.0.0")), - block.chainid, + 5, 0xd9145CCE52D386f254917e481eB44e9943F39138 //this should be address(this) )); diff --git a/problemVersion1/55/problem55.txt b/problemVersion1/55/problem55.txt index 4218d73..eca22d2 100644 --- a/problemVersion1/55/problem55.txt +++ b/problemVersion1/55/problem55.txt @@ -1,11 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; +// Ref: https://github.com/dragonfly-xyz/useful-solidity-patterns/tree/main/patterns/eip712-signed-messages + contract answer55 { bytes32 answer; // This is an EIP712 based contract, please complete the part to get the EIP712 hash. - // This hash should pass the requirement below if the signature is valid + // This hash can be use as below and should pass // require(signer == ecrecover(getHash(value, sender), v, r, s)) function getHash(uint256 value, address sender) public returns (bytes32) { @@ -14,9 +16,9 @@ contract answer55 { - + 5, 0xd9145CCE52D386f254917e481eB44e9943F39138 - //the last arg should be address(this), but for judging reasons, please leave this for us. + //the last two arg should be block.chainid and address(this), but for judging reasons, please leave this for us. )); //TODO 2: complete the calculation of structHash @@ -31,6 +33,10 @@ contract answer55 { return answer; } + + + //-------- Below are judging functions ------------ + function getAns() external view returns(bytes32) { return answer; } diff --git a/problemVersion1/56/answer56.sol b/problemVersion1/56/answer56.sol index 3513aa3..a8ecf01 100644 --- a/problemVersion1/56/answer56.sol +++ b/problemVersion1/56/answer56.sol @@ -31,12 +31,12 @@ contract ProxyContract { contract answer56 { Called called = new Called(); ProxyContract proxy = new ProxyContract(address(called)); - Called proxified = Called(address(proxy)); + Called proxied = Called(address(proxy)); function test() external { - proxified.setMessage("hi"); + proxied.setMessage("hi"); } function getAns() external view returns (string memory) { - return proxified.message(); + return proxied.message(); } } \ No newline at end of file diff --git a/problemVersion1/56/problem56.txt b/problemVersion1/56/problem56.txt index 084f8b4..e2bd62c 100644 --- a/problemVersion1/56/problem56.txt +++ b/problemVersion1/56/problem56.txt @@ -1,7 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; +// Ref: https://github.com/dragonfly-xyz/useful-solidity-patterns/tree/main/patterns/basic-proxies + // In this problem, we are going to write a proxy contract for `Called` +// Proxy Contract combines delegateCall and fallback function contract Called { string public message; @@ -17,7 +20,8 @@ contract ProxyContract { //TODO 1: write a constructor and assign value to `called` - //TODO 2: write a fallback function which should delegate call the proxified `Called` contract + + //TODO 2: write a fallback function which should delegate call the proxied `Called` contract @@ -25,15 +29,17 @@ contract ProxyContract { } + + contract answer56 { Called called = new Called(); ProxyContract proxy = new ProxyContract(address(called)); - Called proxified = Called(address(proxy)); + Called proxied = Called(address(proxy)); function test() external { - proxified.setMessage("hi"); + proxied.setMessage("hi"); } function getAns() external view returns (string memory) { - return proxified.message(); + return proxied.message(); } } \ No newline at end of file diff --git a/problemVersion1/57/problem57.txt b/problemVersion1/57/problem57.txt index 084f8b4..9e1ab2f 100644 --- a/problemVersion1/57/problem57.txt +++ b/problemVersion1/57/problem57.txt @@ -1,39 +1,142 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -// In this problem, we are going to write a proxy contract for `Called` -contract Called { - string public message; +// In this problem, we are going to write a lending contract. +// CollateralERC20 contract is used to pretend as a collateral, to borrow BorrowedERC20 - function setMessage(string memory _message) external { - message = _message; +contract CollateralERC20 { + uint256 public totalSupply = 1000; + mapping(address => uint256) public balanceOf; + + constructor(address owner) { + balanceOf[owner] = totalSupply; + } + + function transferFrom(address from, address to, uint256 amount) external { + balanceOf[from] -= amount; + balanceOf[to] += amount; + } + function transfer(address to, uint256 amount) external { + balanceOf[msg.sender] -= amount; + balanceOf[to] += amount; + } +} + +contract BorrowedERC20 { + uint256 public totalSupply = 1000; + mapping(address => uint256) public balanceOf; + + constructor(address owner) { + balanceOf[owner] = totalSupply; + } + + function transferFrom(address from, address to, uint256 amount) external { + balanceOf[from] -= amount; + balanceOf[to] += amount; + + } + function transfer(address to, uint256 amount) external { + balanceOf[msg.sender] -= amount; + balanceOf[to] += amount; } } +// answer57 is a lending contract, please modify it. +contract answer57 { + BorrowedERC20 public borrowedToken; + CollateralERC20 public collateralToken; + // borrowRatio means that you can only borrow the ratio of the value of your collateral + uint256 borrowRatio = 80; + uint256 borrowedPrice = 100; + uint256 collateralPrice = 100; + mapping(address => address) public s_tokenToPriceFeed; + address[] public s_allowedTokens; + mapping(address => uint256) public deposits; + mapping(address => uint256) public borrows; -contract ProxyContract { - address immutable called; + // 5% Liquidation Reward + uint256 public constant LIQUIDATION_REWARD = 5; + // At 80% Loan to Value Ratio, the loan can be liquidated + uint256 public constant LIQUIDATION_THRESHOLD = 80; + uint256 public constant MIN_HEALH_FACTOR = 1e18; - //TODO 1: write a constructor and assign value to `called` - - //TODO 2: write a fallback function which should delegate call the proxified `Called` contract - + constructor() { + borrowedToken = new BorrowedERC20(address(this)); + collateralToken = new CollateralERC20(msg.sender); + } + // TODO1: this function is for borrower to deposit his collateral, you should modify `deposits` and transfer some token + function depositCollateral(uint256 amount) external { -} + } -contract answer56 { - Called called = new Called(); - ProxyContract proxy = new ProxyContract(address(called)); - Called proxified = Called(address(proxy)); - function test() external { - proxified.setMessage("hi"); - } - function getAns() external view returns (string memory) { - return proxified.message(); - } -} \ No newline at end of file + function withdraw(uint256 amount) external { + require(deposits[msg.sender] >= amount, "Not enough funds"); + + //TODO 2: Complete this requirement, it should require that, + // The left collateral value be bigger that a amount. + // hint: you may need borrowRatio + require( + ( + + + , "Not enough collateral" + ); + deposits[msg.sender] -= amount; + collateralToken.transfer(msg.sender, amount); + } + + function borrow(uint256 amount) external { + require(borrowedToken.balanceOf(address(this)) >= amount, "Not enough tokens to borrow"); + + // TODO 3: Complete the requirement, it should require that the borrow value be less than an amount + require( + + + ,"Not enough collateral" + ); + borrows[msg.sender] += amount; + borrowedToken.transfer(msg.sender, amount); + } + + function repay(uint256 amount) external { + borrows[msg.sender] -= amount; + borrowedToken.transferFrom(msg.sender, address(this), amount); + } + + function liquidate(address account) external { + + require(canBeLiquidated(account), "Account can't be liquidated!"); + uint256 reward = deposits[account] * LIQUIDATION_REWARD / 100; + collateralToken.transfer(msg.sender, reward); + delete borrows[msg.sender]; + delete deposits[msg.sender]; + + } + + function canBeLiquidated(address _account) public view returns (bool) { + uint256 borrowedValue = borrows[_account] * borrowedPrice; + uint256 depositValue = deposits[_account] * collateralPrice; + uint256 liquidatedValue = borrowedValue * LIQUIDATION_THRESHOLD * MIN_HEALH_FACTOR / 100; + return depositValue * MIN_HEALH_FACTOR <= liquidatedValue ? true : false; + } + + + + //----------Below are judging functions------------------- + + function setPrice(uint256 _price1, uint256 _price2) external { + borrowedPrice = _price1; + collateralPrice = _price2; + } + function getCollateralBalanceOf() external view returns (uint256) { + return collateralToken.balanceOf(msg.sender); + } + function getBorrowedTokenBalanceOf() external view returns (uint256) { + return borrowedToken.balanceOf(msg.sender); + } +} diff --git a/problemVersion1/58/problem58.txt b/problemVersion1/58/problem58.txt index 722d6e1..43c7340 100644 --- a/problemVersion1/58/problem58.txt +++ b/problemVersion1/58/problem58.txt @@ -34,18 +34,19 @@ contract Token2 { } } - +// The swap contract is here contract answer58 { Token1 public token1Contract; Token2 public token2Contract; address public token1; address public token2; - //`reserves` is a mapping that maps the reserves amount, for the reasons that many swap pairs may be added. - //for example: reserves[token1][token2] means the token1 reserves in the token1/2 pair. + // `reserves` is a mapping that maps the reserves amount, for the reasons that many swap pairs may be added. + // for example: reserves[token1][token2] means the token1 reserves in the token1/2 pair. mapping(address => mapping(address => uint256)) public reserves; - //`deposits` record the one who deposit tokens to this contract for liquidity. - //We may want to give him some interest. For simple, we wont do that. + + // `deposits` record the one who deposit tokens to this contract for liquidity. + // We may want to give him some interest. To be simpler, we wont do that. mapping(address => mapping(address => mapping(address => uint256))) public deposits; // We make token1 and token2s totalSupply all yours! @@ -59,7 +60,7 @@ contract answer58 { //============ TODOs are below this line ================= function addReserves1(uint256 amount1) external { require(amount1 > 0, "Invalid reserve amount"); - //TODO1: transfer token1 to this contract, don't forget to modify `reserves` and `deposits` + // TODO1: transfer token1 to this contract, don't forget to modify `reserves` and `deposits` diff --git a/problemVersion1/59/problem59.json b/problemVersion1/59/problem59.json index 36fd1e2..6ef037c 100644 --- a/problemVersion1/59/problem59.json +++ b/problemVersion1/59/problem59.json @@ -38,6 +38,16 @@ "methodName": "getStableCoinBalanceOf(address)", "callData": ["MSG_SENDER"], "expectReturn": [100] + }, + { + "methodName": "createCallOption(uint256,uint256,uint256,uint256)", + "callData": [2,5,10,16848343], + "expectReturn": [] + }, + { + "methodName": "%cancelOption(uint256)", + "callData": [2], + "expectReturn": ["hasnt expired"] } ], "attributes": [ diff --git a/problemVersion1/59/problem59.txt b/problemVersion1/59/problem59.txt index 55ee102..5010a18 100644 --- a/problemVersion1/59/problem59.txt +++ b/problemVersion1/59/problem59.txt @@ -1,6 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +// This is an DeFi Option contract ! Please make sure you know what is an Option. +// In this Problem, we are going to deal with CALL options. + contract MockERC20 { uint256 public totalSupply = 100; mapping(address => uint256) public balanceOf; @@ -37,8 +40,6 @@ contract StableCoin { } } -// This is an DeFi Option contract ! Please make sure you know what is an Option. -// In this Problem, we are going to deal with CALL options. contract answer59 { enum OptionType { CALL, @@ -83,7 +84,10 @@ contract answer59 { require(amount > 0, "Invalid amount"); // TODO1: finish declaring a option - options[optionId_] = + options[optionId_] = Option( + + + ) optionId_ ++; return optionId_ - 1; @@ -125,6 +129,10 @@ contract answer59 { function cancelOption(uint256 _optionId) external { Option memory option = options[_optionId]; // TODO5: finish the requirements + // This function should only be called by writer, and of course, shouldn't be expired or exercised. + // hint: there should be three requires + + erc20.transfer(msg.sender, option.amount); @@ -132,7 +140,7 @@ contract answer59 { } - //=========utils==================== + //------------Below are judging functions---------- function addTime() external { nowTime += 1; } diff --git a/problemVersion1/6/problem6.sol b/problemVersion1/6/problem6.sol new file mode 100644 index 0000000..d12019a --- /dev/null +++ b/problemVersion1/6/problem6.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; +contract answer6 { + // Log("fallback", ) for example. + event Log(string method, uint256 amount); + + + // TODO1: Declare a fallback function which returns the calldata, and emit the event `Log`. + + + + // TODO2: Declare a receive function which emit the event `Log`. + + +} \ No newline at end of file diff --git a/problemVersion1/6/problem6.txt b/problemVersion1/6/problem6.txt deleted file mode 100644 index 09f9b6d..0000000 --- a/problemVersion1/6/problem6.txt +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; -contract answer6 { - // `method`: "fallback" for fallback function, and the value sent to this contract for `amount` - event Log(string method, uint256 amount); - - // declare a fallback function which returns the calldata, and emit the event `Log`. - - - // declare a receive function which emit the event `Log`. - - -} \ No newline at end of file diff --git a/problemVersion1/60/problem60.txt b/problemVersion1/60/problem60.txt index 693e063..f366ec1 100644 --- a/problemVersion1/60/problem60.txt +++ b/problemVersion1/60/problem60.txt @@ -1,5 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +// This is a Put Option ! Be sure you know what is put option +// Make sure you finished the Call option problem +// In this problem, you are going to write functions similiar to that, but the logic is quite different. contract MockERC20 { uint256 public totalSupply = 100; @@ -37,9 +40,7 @@ contract StableCoin { } } -// This is a Put Option ! Be sure you know what is put option -// Make sure you finished the Call option problem -// In this problem, you are going to write functions similiar to that, but the logic is quite different. + contract answer60 { enum OptionType { CALL, @@ -76,10 +77,12 @@ contract answer60 { } // TODO1: finish `createPutOption` function + // hint: It is like the Call option function createPutOption(uint256 amount, uint256 price, uint256 strikePrice, uint256 expiration) external returns (uint256) { + @@ -95,7 +98,7 @@ contract answer60 { } - // TODO3: finish `exercisePutOption` function + function exercisePutOption(uint256 _optionId, uint256 amount) external { Option memory option = options[_optionId]; require(msg.sender == option.owner, "not buyer"); @@ -103,28 +106,30 @@ contract answer60 { require(option.expiration <= nowTime, "hasnt expire"); require(option.amount >= amount, "not enough amount"); - uint256 totalPrice = - stableCoin.transferFrom( ); - erc20.transferFrom( ); + // TODO 3 (last): fill in the blanks + uint256 totalPrice = + stableCoin.transferFrom( ); + erc20.transferFrom( ); uint256 lastStableCoin = + + erc20.transferFrom(address(this), option.writer, lastStableCoin); options[_optionId].optionState = OptionState.Exercised; } - // TODO4: finish `cancelOption` function + function cancelOption(uint256 _optionId) external { Option memory option = options[_optionId]; require(msg.sender == option.writer, "not writer"); require(option.expiration < nowTime, "hasnt expired"); require(option.optionState == OptionState.Bought, "not bought or exercised"); - stableCoin.transfer( ); - + stableCoin.transfer(msg.sender, option.amount * option.strikePrice); options[_optionId].optionState = OptionState.Cancelled; } - //==========utils=========================== + //-----------Below are judging functions---------- function addTime() external { nowTime += 1; } diff --git a/problemVersion1/7/problem7.txt b/problemVersion1/7/problem7.txt index 0949b00..349f0eb 100644 --- a/problemVersion1/7/problem7.txt +++ b/problemVersion1/7/problem7.txt @@ -1,8 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; + +// Function overlaod! Same function name for different inputs. contract answer7 { - // TODO: Write functions named `add` to add two uint256 inputs or three uint256 inputs. - // Users should be able to call `add(100,200)` and get 300, call `add(100, 200, 300)` to get 600. + // TODO: Write functions named `add`, + // which add two uint256 inputs or three uint256 as params. + // Requirement: Users should be able to call `add(100,200)` + // and get 300, call `add(100, 200, 300)` to get 600. + + + } \ No newline at end of file diff --git a/problemVersion1/79/problem79.txt b/problemVersion1/79/problem79.txt index 86dbb05..211ac43 100644 --- a/problemVersion1/79/problem79.txt +++ b/problemVersion1/79/problem79.txt @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; +// Ref: https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies + interface IVersioned { function getVersion() external view returns (uint256); } @@ -36,18 +38,21 @@ contract answer79 is IVersioned { fallback() external { address _impl = implementation; - // TODO1: please complete the code below so that others can call any functions in the proxied contract. + // TODO 1: please complete the code below so that others can call any functions in the proxied contract. assembly { + + + } } - // TODO2: write a function named `upgradeImplementation` taking and adress as param - // It should let someone update the contract. - function upgradeImplementation(address newImplementation) public { - implementation = newImplementation; - } + // TODO 2: write a function named `upgradeImplementation` taking and adress as param + // It should let someone update the contract to the input address. + + + function getVersion() external view override returns (uint256) { return IVersioned(implementation).getVersion(); @@ -57,9 +62,6 @@ contract answer79 is IVersioned { v2 = new MyContractV2(); upgradeImplementation(address(v2)); } - - - } diff --git a/problemVersion1/8/problem8.txt b/problemVersion1/8/problem8.txt index d4df75f..947bf9a 100644 --- a/problemVersion1/8/problem8.txt +++ b/problemVersion1/8/problem8.txt @@ -1,9 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -// 1. The system will call the three functions first and they should all revert. -// 2. then the system call `addNumByOne` -// 3. After that the system will call the three functions and they should all pass without any error message -// 4. DO NOTHNG after the requirements. + +// This problem is about errors + contract answer8 { uint256 public balance = 0; @@ -11,13 +10,25 @@ contract answer8 { // TODO: Write a function named `testAssert` using `assert` + // TODO: Write a function named `testRequire` using `require`, the error message should be "Required" if reverted. + // TODO: Write a function named `testRevert` using `revert`, the error message should be "Reverted" if reverted. + + // The system will do these steps: + // 1. Call the three functions first and they should all revert. + // 2. Call `addNumByOne` + // 3. Call the three functions and they should all pass without any error message + + // hint: use `balance` as your requirement + + // --------------Below are judging functions------------------- + function addNumByOne() external { balance++; } diff --git a/problemVersion1/80/problem80.txt b/problemVersion1/80/problem80.txt index 3d30005..90517ff 100644 --- a/problemVersion1/80/problem80.txt +++ b/problemVersion1/80/problem80.txt @@ -33,12 +33,15 @@ contract answer80 { mapping(string => address) symbols; function createToken(string memory _name, string memory _symbol, uint256 _totalSupply) public { - // TODO: complete this function, think of the requirements to be satisfied + // TODO: complete this function + // It should deploy new contract, be sure not to use the same symbol + } + //-----------Below are judging functions---------- function checkAns(string memory _symbol) external view returns (bool) { return tokens[0] == symbols[_symbol] ? true : false; } diff --git a/problemVersion1/81/answer81.sol b/problemVersion1/81/answer81.sol index 5004ac7..f436068 100644 --- a/problemVersion1/81/answer81.sol +++ b/problemVersion1/81/answer81.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.17; pragma solidity ^0.8.0; -contract EscowedToken { +contract escrowedToken { uint256 public totalSupply = 100; mapping(address => uint256) public balanceOf; @@ -29,15 +29,15 @@ contract answer81 { uint public amount; bool public approvedByBuyer; bool public approvedByArbiter; - EscowedToken escowed; + escrowedToken escrowed; constructor() { - escowed = new EscowedToken(msg.sender); + escrowed = new escrowedToken(msg.sender); buyer = msg.sender; seller = msg.sender; arbiter = msg.sender; amount = 50; - escowed.transferFrom(msg.sender, address(this), 50); + escrowed.transferFrom(msg.sender, address(this), 50); } function approveByBuyer() public { @@ -52,11 +52,11 @@ contract answer81 { function releaseAmount() public { require(approvedByBuyer && approvedByArbiter, "not approved"); - escowed.transfer(buyer, amount); + escrowed.transfer(buyer, amount); } function refundAmount() public { require(!approvedByBuyer || !approvedByArbiter, "has already approved"); - escowed.transfer(seller, amount); + escrowed.transfer(seller, amount); } } diff --git a/problemVersion1/81/problem81.txt b/problemVersion1/81/problem81.txt index 87d7593..c747bf2 100644 --- a/problemVersion1/81/problem81.txt +++ b/problemVersion1/81/problem81.txt @@ -3,7 +3,7 @@ pragma solidity ^0.8.17; pragma solidity ^0.8.0; -contract EscowedToken { +contract escrowedToken { uint256 public totalSupply = 100; mapping(address => uint256) public balanceOf; @@ -21,7 +21,7 @@ contract EscowedToken { } } -// This is an escow contract ! Facilitates the exchange of goods or services between a buyer, seller, and an arbiter. +// This is an escrow contract ! Facilitates the exchange of goods or services between a buyer, seller, and an arbiter. contract answer81 { address public buyer; address public seller; @@ -29,15 +29,15 @@ contract answer81 { uint public amount; bool public approvedByBuyer; bool public approvedByArbiter; - EscowedToken escowed; + escrowedToken escrowed; constructor() { - escowed = new EscowedToken(msg.sender); + escrowed = new escrowedToken(msg.sender); buyer = msg.sender; seller = msg.sender; arbiter = msg.sender; amount = 50; - escowed.transferFrom(msg.sender, address(this), 50); + escrowed.transferFrom(msg.sender, address(this), 50); } // TODOs: Complete the functions below, think of the requirements needs to be satisfied. diff --git a/problemVersion1/83/problem83.txt b/problemVersion1/83/problem83.txt index ebb3eb7..e09ee67 100644 --- a/problemVersion1/83/problem83.txt +++ b/problemVersion1/83/problem83.txt @@ -41,7 +41,7 @@ contract RewardToken { contract answer83 { StakingToken public stakingToken; RewardToken public rewardToken; - // for the reason of judging, we use nowTime as block.timestamp + // for the reason of judging, we use nowTime to mock block.timestamp uint256 public nowTime = 16848340; uint256 public rewardPerSecond = 1; @@ -53,12 +53,15 @@ contract answer83 { rewardToken = new RewardToken(address(this)); } - // TODO2: finish `stake` + function stake(uint256 _amount) external { require(_amount > 0, "Staking amount must be greater than 0"); uint256 currentTimestamp = nowTime; - uint256 staked = - uint256 stakedAt = + + // TODO 1 is below here, do it first! + // TODO 2: fill in the blanks + uint256 staked = stakedAmount[msg.sender]; + uint256 stakedAt = stakedTimestamp[msg.sender]; if (staked > 0) { uint256 pendingReward = if (pendingReward > 0) { @@ -78,28 +81,32 @@ contract answer83 { uint256 stakedAt = stakedTimestamp[msg.sender]; // calculate reward and transfer it + uint256 pendingReward = + if(pendingReward > 0) { - // modify these + + } stakedAmount[msg.sender] = stakedTimestamp[msg.sender] = stakingToken.transfer( , ); + } - + // Calculate the staking rewards function calculateReward(uint256 _amount, uint256 _currentTimestamp, uint256 _stakedTimestamp) public view returns (uint256) { - // TODO1: the reward has to be calculated + // TODO1: uint256 reward = return reward; } - // ======== utils ====================== + // ---------Below are judging functions------- function addTime() external { nowTime += 1; } diff --git a/problemVersion1/84/problem84.txt b/problemVersion1/84/problem84.txt index 188bfaf..1318bc6 100644 --- a/problemVersion1/84/problem84.txt +++ b/problemVersion1/84/problem84.txt @@ -38,7 +38,7 @@ contract RewardToken { } // This is an advanced staking contract ! We added slash and delegate functions. -// We are only focusing slashing. +// We are only focusing on slashing. contract answer84 { StakingToken public stakingToken; RewardToken public rewardToken; @@ -132,12 +132,12 @@ contract answer84 { function slash(address _staker) external onlyOwner { require(!slashed[_staker], "Already slashed"); - // TODO1 : fill in the blanks + // TODO 1 : fill in the blanks uint256 amountToSlash = require(amountToSlash > 0, "Amount to slash must be greater than 0"); - slashed[_staker] = - totalStaked -= + slashed[_staker] = true; + totalStaked -= amountToSlash; stakedBalance[_staker] -= totalRewards -= / 1e18; @@ -160,7 +160,7 @@ contract answer84 { uint256 rewardPerSecond = rewardRate ; uint256 timeDelta = nowTime - lastUpdateTime; - // TODO2: finish calculate the `rewardAccumulated` + // TODO 2: finish calculate the `rewardAccumulated` uint256 rewardAccumulated = * 1e18; rewardPerTokenStored += rewardAccumulated / totalStaked; lastUpdateTime = nowTime; diff --git a/problemVersion1/85/problem85.txt b/problemVersion1/85/problem85.txt index 4c045aa..36b6051 100644 --- a/problemVersion1/85/problem85.txt +++ b/problemVersion1/85/problem85.txt @@ -59,12 +59,11 @@ contract answer85 { erc20 = new LeveragedToken(address(this)); } - // When a person opens a leverage transaction, our contract calculates how much stableCoin he puts in, - // then transfer the amount of an erc20 token to him. + // When a person opens a leverage transaction, our contract calculates how much stableCoin he puts in, then transfer the amount of an erc20 token to him. function open(uint256 _collateral) external { // TODO1: calculate the amount that has to be transfered, - // do not forget the leverageRatio, and the erc20price + // dont forget the leverageRatio, and the erc20price uint256 amount = positions[msg.sender] = Position(_collateral, amount, erc20Price); stableCoin.transferFrom(msg.sender, address(this), _collateral); @@ -90,13 +89,15 @@ contract answer85 { delete positions[msg.sender]; } + // Liquidate function can be called by anyone. + // In fact we should encourage people to help liquidate by giving rewards. But for simple, we will skip that. function liquidate(address user) external { Position memory position = positions[user]; require(position.collateral > 0, "No open position"); uint openPrice = position.openPrice; //TODO3: determine whether the position can be liquidated - require( , "The position is safe"); + require( , "The position is safe"); //TODO4: if liquidated, the liquidated position should return the erc20, and we should delete this position. diff --git a/problemVersion1/9/problem9.txt b/problemVersion1/9/problem9.txt index 1eeeead..05b5e62 100644 --- a/problemVersion1/9/problem9.txt +++ b/problemVersion1/9/problem9.txt @@ -1,8 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -// The system will only deploy `answer9()`, write the code in the constructor. -// The system will call `checkAns()` to check your answer. + contract toBeDeployed { bool public deployed; @@ -27,6 +26,10 @@ contract answer9 { } + // The system will only deploy `answer9()`. + + // --------------Below are judging functions------------------- + function checkAns() external view returns (bool) { return deployContract.getDeployed(); } diff --git a/scripts/judgeGanache.ts b/scripts/judgeGanache.ts index 06c2d42..598464a 100644 --- a/scripts/judgeGanache.ts +++ b/scripts/judgeGanache.ts @@ -31,10 +31,12 @@ async function main() { } console.log(nonCompletedProblems) + console.log(nonCompletedProblems) } else { await judge(problemNumber, provider) } + console.log(nonCompletedProblems) } async function judge(problemNumber: number, provider: any) {