mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #4321 from ethereum/contractConversion
[BREAKING] Disallow conversion between unrelated contract types.
This commit is contained in:
		
						commit
						ef269bf40d
					
				| @ -40,6 +40,7 @@ Breaking Changes: | |||||||
|  * Type Checker: Disallow arithmetic operations for boolean variables. |  * Type Checker: Disallow arithmetic operations for boolean variables. | ||||||
|  * Type Checker: Disallow tight packing of literals. This was already the case in the experimental 0.5.0 mode. |  * Type Checker: Disallow tight packing of literals. This was already the case in the experimental 0.5.0 mode. | ||||||
|  * Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size. |  * Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size. | ||||||
|  |  * Type Checker: Disallow conversions between unrelated contract types. Explicit conversion via ``address`` can still achieve it. | ||||||
|  * Type Checker: Disallow empty tuple components. This was partly already the case in the experimental 0.5.0 mode. |  * Type Checker: Disallow empty tuple components. This was partly already the case in the experimental 0.5.0 mode. | ||||||
|  * Type Checker: Disallow multi-variable declarations with mismatching number of values. This was already the case in the experimental 0.5.0 mode. |  * Type Checker: Disallow multi-variable declarations with mismatching number of values. This was already the case in the experimental 0.5.0 mode. | ||||||
|  * Type Checker: Disallow specifying base constructor arguments multiple times in the same inheritance hierarchy. This was already the case in the experimental 0.5.0 mode. |  * Type Checker: Disallow specifying base constructor arguments multiple times in the same inheritance hierarchy. This was already the case in the experimental 0.5.0 mode. | ||||||
|  | |||||||
| @ -1,5 +1,7 @@ | |||||||
| .. index:: ! contract | .. index:: ! contract | ||||||
| 
 | 
 | ||||||
|  | .. _contracts: | ||||||
|  | 
 | ||||||
| ########## | ########## | ||||||
| Contracts | Contracts | ||||||
| ########## | ########## | ||||||
|  | |||||||
| @ -379,7 +379,7 @@ In this example:: | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     contract A { |     contract A { | ||||||
|         address child; |         B child; | ||||||
| 
 | 
 | ||||||
|         function test() public { |         function test() public { | ||||||
|             child = (new B).value(10)(); //construct a new B with 10 wei |             child = (new B).value(10)(); //construct a new B with 10 wei | ||||||
|  | |||||||
| @ -192,6 +192,23 @@ The ``.gas()`` option is available on all three methods, while the ``.value()`` | |||||||
| .. note:: | .. note:: | ||||||
|     The use of ``callcode`` is discouraged and will be removed in the future. |     The use of ``callcode`` is discouraged and will be removed in the future. | ||||||
| 
 | 
 | ||||||
|  | Contract Types | ||||||
|  | -------------- | ||||||
|  | 
 | ||||||
|  | Every :ref:`contract<contracts>` defines its own type. Contracts can be implicitly converted | ||||||
|  | to contracts they inherit from. They can be explicitly converted from and to ``address`` types. | ||||||
|  | 
 | ||||||
|  | The data representation of a contract is identical to that of the ``address`` type and | ||||||
|  | this type is also used in the :ref:`ABI<ABI>`. | ||||||
|  | 
 | ||||||
|  | Contracts do not support any operators. | ||||||
|  | 
 | ||||||
|  | The members of contract types are the external functions of the contract including | ||||||
|  | public state variables. | ||||||
|  | 
 | ||||||
|  | .. note:: | ||||||
|  |     Starting with version 0.5.0 contracts do not derive from the address type, but can still be explicitly converted to address. | ||||||
|  | 
 | ||||||
| .. index:: byte array, bytes32 | .. index:: byte array, bytes32 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -884,7 +901,7 @@ for each ``_KeyType``, recursively. | |||||||
|         function f() public returns (uint) { |         function f() public returns (uint) { | ||||||
|             MappingExample m = new MappingExample(); |             MappingExample m = new MappingExample(); | ||||||
|             m.update(100); |             m.update(100); | ||||||
|             return m.balances(this); |             return m.balances(address(this)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1403,15 +1403,15 @@ bool ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const | |||||||
| { | { | ||||||
| 	if (*this == _convertTo) | 	if (*this == _convertTo) | ||||||
| 		return true; | 		return true; | ||||||
| 	if (_convertTo.category() == Category::Integer) |  | ||||||
| 		return dynamic_cast<IntegerType const&>(_convertTo).isAddress(); |  | ||||||
| 	if (_convertTo.category() == Category::Contract) | 	if (_convertTo.category() == Category::Contract) | ||||||
| 	{ | 	{ | ||||||
| 		auto const& bases = contractDefinition().annotation().linearizedBaseContracts; | 		auto const& bases = contractDefinition().annotation().linearizedBaseContracts; | ||||||
| 		if (m_super && bases.size() <= 1) | 		if (m_super && bases.size() <= 1) | ||||||
| 			return false; | 			return false; | ||||||
| 		return find(m_super ? ++bases.begin() : bases.begin(), bases.end(), | 		return find( | ||||||
| 					&dynamic_cast<ContractType const&>(_convertTo).contractDefinition()) != bases.end(); | 			m_super ? ++bases.begin() : bases.begin(), bases.end(), | ||||||
|  | 			&dynamic_cast<ContractType const&>(_convertTo).contractDefinition() | ||||||
|  | 		) != bases.end(); | ||||||
| 	} | 	} | ||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
| @ -1420,8 +1420,7 @@ bool ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const | |||||||
| { | { | ||||||
| 	return | 	return | ||||||
| 		isImplicitlyConvertibleTo(_convertTo) || | 		isImplicitlyConvertibleTo(_convertTo) || | ||||||
| 		_convertTo.category() == Category::Integer || | 		_convertTo == IntegerType(160, IntegerType::Modifier::Address); | ||||||
| 		_convertTo.category() == Category::Contract; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool ContractType::isPayable() const | bool ContractType::isPayable() const | ||||||
|  | |||||||
| @ -692,9 +692,9 @@ public: | |||||||
| 	virtual Category category() const override { return Category::Contract; } | 	virtual Category category() const override { return Category::Contract; } | ||||||
| 	explicit ContractType(ContractDefinition const& _contract, bool _super = false): | 	explicit ContractType(ContractDefinition const& _contract, bool _super = false): | ||||||
| 		m_contract(_contract), m_super(_super) {} | 		m_contract(_contract), m_super(_super) {} | ||||||
| 	/// Contracts can be implicitly converted to super classes and to addresses.
 | 	/// Contracts can be implicitly converted only to base contracts.
 | ||||||
| 	virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; | 	virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; | ||||||
| 	/// Contracts can be converted to themselves and to integers.
 | 	/// Contracts can only be explicitly converted to address types and base contracts.
 | ||||||
| 	virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; | 	virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; | ||||||
| 	virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; | 	virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; | ||||||
| 	virtual std::string richIdentifier() const override; | 	virtual std::string richIdentifier() const override; | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ contract MultiSigWalletFactory is Factory { | |||||||
|         public |         public | ||||||
|         returns (address wallet) |         returns (address wallet) | ||||||
|     { |     { | ||||||
|         wallet = new MultiSigWallet(_owners, _required); |         wallet = address(new MultiSigWallet(_owners, _required)); | ||||||
|         register(wallet); |         register(wallet); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ contract MultiSigWalletWithDailyLimitFactory is Factory { | |||||||
|         public |         public | ||||||
|         returns (address wallet) |         returns (address wallet) | ||||||
|     { |     { | ||||||
|         wallet = new MultiSigWalletWithDailyLimit(_owners, _required, _dailyLimit); |         wallet = address(new MultiSigWalletWithDailyLimit(_owners, _required, _dailyLimit)); | ||||||
|         register(wallet); |         register(wallet); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -56,7 +56,7 @@ contract premium is module, safeMath { | |||||||
|         require( dbAddress != address(0x00) ); |         require( dbAddress != address(0x00) ); | ||||||
|         db = ptokenDB(dbAddress); |         db = ptokenDB(dbAddress); | ||||||
|         if ( ! forReplace ) { |         if ( ! forReplace ) { | ||||||
|             require( db.replaceOwner(this) ); |             require( db.replaceOwner(address(this)) ); | ||||||
|             isICO = true; |             isICO = true; | ||||||
|             icoAddr = icoContractAddr; |             icoAddr = icoContractAddr; | ||||||
|             assert( genesisAddr.length == genesisValue.length ); |             assert( genesisAddr.length == genesisValue.length ); | ||||||
|  | |||||||
| @ -259,7 +259,7 @@ contract schelling is module, announcementTypes, schellingVars { | |||||||
|         db = schellingDB(_db); |         db = schellingDB(_db); | ||||||
|         super.registerModuleHandler(_moduleHandler); |         super.registerModuleHandler(_moduleHandler); | ||||||
|         if ( ! _forReplace ) { |         if ( ! _forReplace ) { | ||||||
|             require( db.replaceOwner(this) ); |             require( db.replaceOwner(address(this)) ); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     function configure(announcementType a, uint256 b) external returns(bool) { |     function configure(announcementType a, uint256 b) external returns(bool) { | ||||||
|  | |||||||
| @ -71,7 +71,7 @@ contract token is safeMath, module, announcementTypes { | |||||||
|         exchangeAddress = exchangeContractAddress; |         exchangeAddress = exchangeContractAddress; | ||||||
|         isICO = ! forReplace; |         isICO = ! forReplace; | ||||||
|         if ( ! forReplace ) { |         if ( ! forReplace ) { | ||||||
|             require( db.replaceOwner(this) ); |             require( db.replaceOwner(address(this)) ); | ||||||
|             assert( genesisAddr.length == genesisValue.length ); |             assert( genesisAddr.length == genesisValue.length ); | ||||||
|             require( address(this).balance >= genesisAddr.length * 0.2 ether ); |             require( address(this).balance >= genesisAddr.length * 0.2 ether ); | ||||||
|             for ( uint256 a=0 ; a<genesisAddr.length ; a++ ) { |             for ( uint256 a=0 ; a<genesisAddr.length ; a++ ) { | ||||||
|  | |||||||
| @ -54,7 +54,7 @@ contract Event { | |||||||
|         public |         public | ||||||
|     { |     { | ||||||
|         // Transfer collateral tokens to events contract |         // Transfer collateral tokens to events contract | ||||||
|         require(collateralToken.transferFrom(msg.sender, this, collateralTokenCount)); |         require(collateralToken.transferFrom(msg.sender, address(this), collateralTokenCount)); | ||||||
|         // Issue new outcome tokens to sender |         // Issue new outcome tokens to sender | ||||||
|         for (uint8 i = 0; i < outcomeTokens.length; i++) |         for (uint8 i = 0; i < outcomeTokens.length; i++) | ||||||
|             outcomeTokens[i].issue(msg.sender, collateralTokenCount); |             outcomeTokens[i].issue(msg.sender, collateralTokenCount); | ||||||
|  | |||||||
| @ -102,12 +102,12 @@ contract Campaign { | |||||||
|         timedTransitions |         timedTransitions | ||||||
|         atStage(Stages.AuctionStarted) |         atStage(Stages.AuctionStarted) | ||||||
|     { |     { | ||||||
|         uint raisedAmount = eventContract.collateralToken().balanceOf(this); |         uint raisedAmount = eventContract.collateralToken().balanceOf(address(this)); | ||||||
|         uint maxAmount = funding.sub(raisedAmount); |         uint maxAmount = funding.sub(raisedAmount); | ||||||
|         if (maxAmount < amount) |         if (maxAmount < amount) | ||||||
|             amount = maxAmount; |             amount = maxAmount; | ||||||
|         // Collect collateral tokens |         // Collect collateral tokens | ||||||
|         require(eventContract.collateralToken().transferFrom(msg.sender, this, amount)); |         require(eventContract.collateralToken().transferFrom(msg.sender, address(this), amount)); | ||||||
|         contributions[msg.sender] = contributions[msg.sender].add(amount); |         contributions[msg.sender] = contributions[msg.sender].add(amount); | ||||||
|         if (amount == maxAmount) |         if (amount == maxAmount) | ||||||
|             stage = Stages.AuctionSuccessful; |             stage = Stages.AuctionSuccessful; | ||||||
| @ -138,7 +138,7 @@ contract Campaign { | |||||||
|         returns (Market) |         returns (Market) | ||||||
|     { |     { | ||||||
|         market = marketFactory.createMarket(eventContract, marketMaker, fee); |         market = marketFactory.createMarket(eventContract, marketMaker, fee); | ||||||
|         require(eventContract.collateralToken().approve(market, funding)); |         require(eventContract.collateralToken().approve(address(market), funding)); | ||||||
|         market.fund(funding); |         market.fund(funding); | ||||||
|         stage = Stages.MarketCreated; |         stage = Stages.MarketCreated; | ||||||
|         emit MarketCreation(market); |         emit MarketCreation(market); | ||||||
| @ -156,7 +156,7 @@ contract Campaign { | |||||||
|         market.close(); |         market.close(); | ||||||
|         market.withdrawFees(); |         market.withdrawFees(); | ||||||
|         eventContract.redeemWinnings(); |         eventContract.redeemWinnings(); | ||||||
|         finalBalance = eventContract.collateralToken().balanceOf(this); |         finalBalance = eventContract.collateralToken().balanceOf(address(this)); | ||||||
|         stage = Stages.MarketClosed; |         stage = Stages.MarketClosed; | ||||||
|         emit MarketClosing(); |         emit MarketClosing(); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -60,8 +60,8 @@ contract StandardMarket is Market { | |||||||
|         atStage(Stages.MarketCreated) |         atStage(Stages.MarketCreated) | ||||||
|     { |     { | ||||||
|         // Request collateral tokens and allow event contract to transfer them to buy all outcomes |         // Request collateral tokens and allow event contract to transfer them to buy all outcomes | ||||||
|         require(   eventContract.collateralToken().transferFrom(msg.sender, this, _funding) |         require(   eventContract.collateralToken().transferFrom(msg.sender, address(this), _funding) | ||||||
|                 && eventContract.collateralToken().approve(eventContract, _funding)); |                 && eventContract.collateralToken().approve(address(eventContract), _funding)); | ||||||
|         eventContract.buyAllOutcomes(_funding); |         eventContract.buyAllOutcomes(_funding); | ||||||
|         funding = _funding; |         funding = _funding; | ||||||
|         stage = Stages.MarketFunded; |         stage = Stages.MarketFunded; | ||||||
| @ -76,7 +76,7 @@ contract StandardMarket is Market { | |||||||
|     { |     { | ||||||
|         uint8 outcomeCount = eventContract.getOutcomeCount(); |         uint8 outcomeCount = eventContract.getOutcomeCount(); | ||||||
|         for (uint8 i = 0; i < outcomeCount; i++) |         for (uint8 i = 0; i < outcomeCount; i++) | ||||||
|             require(eventContract.outcomeTokens(i).transfer(creator, eventContract.outcomeTokens(i).balanceOf(this))); |             require(eventContract.outcomeTokens(i).transfer(creator, eventContract.outcomeTokens(i).balanceOf(address(this)))); | ||||||
|         stage = Stages.MarketClosed; |         stage = Stages.MarketClosed; | ||||||
|         emit MarketClosing(); |         emit MarketClosing(); | ||||||
|     } |     } | ||||||
| @ -88,7 +88,7 @@ contract StandardMarket is Market { | |||||||
|         isCreator |         isCreator | ||||||
|         returns (uint fees) |         returns (uint fees) | ||||||
|     { |     { | ||||||
|         fees = eventContract.collateralToken().balanceOf(this); |         fees = eventContract.collateralToken().balanceOf(address(this)); | ||||||
|         // Transfer fees |         // Transfer fees | ||||||
|         require(eventContract.collateralToken().transfer(creator, fees)); |         require(eventContract.collateralToken().transfer(creator, fees)); | ||||||
|         emit FeeWithdrawal(fees); |         emit FeeWithdrawal(fees); | ||||||
| @ -112,8 +112,8 @@ contract StandardMarket is Market { | |||||||
|         // Check cost doesn't exceed max cost |         // Check cost doesn't exceed max cost | ||||||
|         require(cost > 0 && cost <= maxCost); |         require(cost > 0 && cost <= maxCost); | ||||||
|         // Transfer tokens to markets contract and buy all outcomes |         // Transfer tokens to markets contract and buy all outcomes | ||||||
|         require(   eventContract.collateralToken().transferFrom(msg.sender, this, cost) |         require(   eventContract.collateralToken().transferFrom(msg.sender, address(this), cost) | ||||||
|                 && eventContract.collateralToken().approve(eventContract, outcomeTokenCost)); |                 && eventContract.collateralToken().approve(address(eventContract), outcomeTokenCost)); | ||||||
|         // Buy all outcomes |         // Buy all outcomes | ||||||
|         eventContract.buyAllOutcomes(outcomeTokenCost); |         eventContract.buyAllOutcomes(outcomeTokenCost); | ||||||
|         // Transfer outcome tokens to buyer |         // Transfer outcome tokens to buyer | ||||||
| @ -142,7 +142,7 @@ contract StandardMarket is Market { | |||||||
|         // Check profit is not too low |         // Check profit is not too low | ||||||
|         require(profit > 0 && profit >= minProfit); |         require(profit > 0 && profit >= minProfit); | ||||||
|         // Transfer outcome tokens to markets contract to sell all outcomes |         // Transfer outcome tokens to markets contract to sell all outcomes | ||||||
|         require(eventContract.outcomeTokens(outcomeTokenIndex).transferFrom(msg.sender, this, outcomeTokenCount)); |         require(eventContract.outcomeTokens(outcomeTokenIndex).transferFrom(msg.sender, address(this), outcomeTokenCount)); | ||||||
|         // Sell all outcomes |         // Sell all outcomes | ||||||
|         eventContract.sellAllOutcomes(outcomeTokenProfit); |         eventContract.sellAllOutcomes(outcomeTokenProfit); | ||||||
|         // Transfer profit to seller |         // Transfer profit to seller | ||||||
| @ -164,11 +164,11 @@ contract StandardMarket is Market { | |||||||
|         returns (uint cost) |         returns (uint cost) | ||||||
|     { |     { | ||||||
|         // Buy all outcomes |         // Buy all outcomes | ||||||
|         require(   eventContract.collateralToken().transferFrom(msg.sender, this, outcomeTokenCount) |         require(   eventContract.collateralToken().transferFrom(msg.sender, address(this), outcomeTokenCount) | ||||||
|                 && eventContract.collateralToken().approve(eventContract, outcomeTokenCount)); |                 && eventContract.collateralToken().approve(address(eventContract), outcomeTokenCount)); | ||||||
|         eventContract.buyAllOutcomes(outcomeTokenCount); |         eventContract.buyAllOutcomes(outcomeTokenCount); | ||||||
|         // Short sell selected outcome |         // Short sell selected outcome | ||||||
|         eventContract.outcomeTokens(outcomeTokenIndex).approve(this, outcomeTokenCount); |         eventContract.outcomeTokens(outcomeTokenIndex).approve(address(this), outcomeTokenCount); | ||||||
|         uint profit = this.sell(outcomeTokenIndex, outcomeTokenCount, minProfit); |         uint profit = this.sell(outcomeTokenIndex, outcomeTokenCount, minProfit); | ||||||
|         cost = outcomeTokenCount - profit; |         cost = outcomeTokenCount - profit; | ||||||
|         // Transfer outcome tokens to buyer |         // Transfer outcome tokens to buyer | ||||||
|  | |||||||
| @ -95,14 +95,14 @@ contract FutarchyOracle is Oracle { | |||||||
|         isCreator |         isCreator | ||||||
|     { |     { | ||||||
|         // Buy all outcomes |         // Buy all outcomes | ||||||
|         require(   categoricalEvent.collateralToken().transferFrom(creator, this, funding) |         require(   categoricalEvent.collateralToken().transferFrom(creator, address(this), funding) | ||||||
|                 && categoricalEvent.collateralToken().approve(categoricalEvent, funding)); |                 && categoricalEvent.collateralToken().approve(address(categoricalEvent), funding)); | ||||||
|         categoricalEvent.buyAllOutcomes(funding); |         categoricalEvent.buyAllOutcomes(funding); | ||||||
|         // Fund each market with outcome tokens from categorical event |         // Fund each market with outcome tokens from categorical event | ||||||
|         for (uint8 i = 0; i < markets.length; i++) { |         for (uint8 i = 0; i < markets.length; i++) { | ||||||
|             Market market = markets[i]; |             Market market = markets[i]; | ||||||
|             // Approve funding for market |             // Approve funding for market | ||||||
|             require(market.eventContract().collateralToken().approve(market, funding)); |             require(market.eventContract().collateralToken().approve(address(market), funding)); | ||||||
|             market.fund(funding); |             market.fund(funding); | ||||||
|         } |         } | ||||||
|         emit FutarchyFunding(funding); |         emit FutarchyFunding(funding); | ||||||
| @ -122,7 +122,7 @@ contract FutarchyOracle is Oracle { | |||||||
|         market.withdrawFees(); |         market.withdrawFees(); | ||||||
|         // Redeem collateral token for winning outcome tokens and transfer collateral tokens to creator |         // Redeem collateral token for winning outcome tokens and transfer collateral tokens to creator | ||||||
|         categoricalEvent.redeemWinnings(); |         categoricalEvent.redeemWinnings(); | ||||||
|         require(categoricalEvent.collateralToken().transfer(creator, categoricalEvent.collateralToken().balanceOf(this))); |         require(categoricalEvent.collateralToken().transfer(creator, categoricalEvent.collateralToken().balanceOf(address(this)))); | ||||||
|         emit FutarchyClosing(); |         emit FutarchyClosing(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -92,7 +92,7 @@ contract UltimateOracle is Oracle { | |||||||
|         // There was no challenge yet or the challenge period expired |         // There was no challenge yet or the challenge period expired | ||||||
|         require(   !isChallenged() |         require(   !isChallenged() | ||||||
|                 && !isChallengePeriodOver() |                 && !isChallengePeriodOver() | ||||||
|                 && collateralToken.transferFrom(msg.sender, this, challengeAmount)); |                 && collateralToken.transferFrom(msg.sender, address(this), challengeAmount)); | ||||||
|         outcomeAmounts[msg.sender][_outcome] = challengeAmount; |         outcomeAmounts[msg.sender][_outcome] = challengeAmount; | ||||||
|         totalOutcomeAmounts[_outcome] = challengeAmount; |         totalOutcomeAmounts[_outcome] = challengeAmount; | ||||||
|         totalAmount = challengeAmount; |         totalAmount = challengeAmount; | ||||||
| @ -113,7 +113,7 @@ contract UltimateOracle is Oracle { | |||||||
|         // Outcome is challenged and front runner period is not over yet and tokens can be transferred |         // Outcome is challenged and front runner period is not over yet and tokens can be transferred | ||||||
|         require(   isChallenged() |         require(   isChallenged() | ||||||
|                 && !isFrontRunnerPeriodOver() |                 && !isFrontRunnerPeriodOver() | ||||||
|                 && collateralToken.transferFrom(msg.sender, this, amount)); |                 && collateralToken.transferFrom(msg.sender, address(this), amount)); | ||||||
|         outcomeAmounts[msg.sender][_outcome] = outcomeAmounts[msg.sender][_outcome].add(amount); |         outcomeAmounts[msg.sender][_outcome] = outcomeAmounts[msg.sender][_outcome].add(amount); | ||||||
|         totalOutcomeAmounts[_outcome] = totalOutcomeAmounts[_outcome].add(amount); |         totalOutcomeAmounts[_outcome] = totalOutcomeAmounts[_outcome].add(amount); | ||||||
|         totalAmount = totalAmount.add(amount); |         totalAmount = totalAmount.add(amount); | ||||||
|  | |||||||
| @ -31,8 +31,8 @@ contract Bounty is PullPayment, Destructible { | |||||||
|    */ |    */ | ||||||
|   function createTarget() public returns(Target) { |   function createTarget() public returns(Target) { | ||||||
|     Target target = Target(deployContract()); |     Target target = Target(deployContract()); | ||||||
|     researchers[target] = msg.sender; |     researchers[address(target)] = msg.sender; | ||||||
|     emit TargetCreated(target); |     emit TargetCreated(address(target)); | ||||||
|     return target; |     return target; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -47,7 +47,7 @@ contract Bounty is PullPayment, Destructible { | |||||||
|    * @param target contract |    * @param target contract | ||||||
|    */ |    */ | ||||||
|   function claim(Target target) public { |   function claim(Target target) public { | ||||||
|     address researcher = researchers[target]; |     address researcher = researchers[address(target)]; | ||||||
|     if (researcher == address(0)) { |     if (researcher == address(0)) { | ||||||
|       revert(); |       revert(); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -26,7 +26,7 @@ contract TokenDestructible is Ownable { | |||||||
|     // Transfer tokens to owner |     // Transfer tokens to owner | ||||||
|     for(uint256 i = 0; i < tokens.length; i++) { |     for(uint256 i = 0; i < tokens.length; i++) { | ||||||
|       ERC20Basic token = ERC20Basic(tokens[i]); |       ERC20Basic token = ERC20Basic(tokens[i]); | ||||||
|       uint256 balance = token.balanceOf(this); |       uint256 balance = token.balanceOf(address(this)); | ||||||
|       token.transfer(owner, balance); |       token.transfer(owner, balance); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -28,7 +28,7 @@ contract HasNoTokens is Ownable { | |||||||
|    */ |    */ | ||||||
|   function reclaimToken(address tokenAddr) external onlyOwner { |   function reclaimToken(address tokenAddr) external onlyOwner { | ||||||
|     ERC20Basic tokenInst = ERC20Basic(tokenAddr); |     ERC20Basic tokenInst = ERC20Basic(tokenAddr); | ||||||
|     uint256 balance = tokenInst.balanceOf(this); |     uint256 balance = tokenInst.balanceOf(address(this)); | ||||||
|     tokenInst.transfer(owner, balance); |     tokenInst.transfer(owner, balance); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -33,7 +33,7 @@ contract TokenTimelock { | |||||||
|     require(msg.sender == beneficiary); |     require(msg.sender == beneficiary); | ||||||
|     require(now >= releaseTime); |     require(now >= releaseTime); | ||||||
| 
 | 
 | ||||||
|     uint amount = token.balanceOf(this); |     uint amount = token.balanceOf(address(this)); | ||||||
|     require(amount > 0); |     require(amount > 0); | ||||||
| 
 | 
 | ||||||
|     token.transfer(beneficiary, amount); |     token.transfer(beneficiary, amount); | ||||||
|  | |||||||
| @ -9420,7 +9420,7 @@ BOOST_AUTO_TEST_CASE(failed_create) | |||||||
| 		contract C { | 		contract C { | ||||||
| 			uint public x; | 			uint public x; | ||||||
| 			constructor() public payable {} | 			constructor() public payable {} | ||||||
| 			function f(uint amount) public returns (address) { | 			function f(uint amount) public returns (D) { | ||||||
| 				x++; | 				x++; | ||||||
| 				return (new D).value(amount)(); | 				return (new D).value(amount)(); | ||||||
| 			} | 			} | ||||||
| @ -9428,7 +9428,7 @@ BOOST_AUTO_TEST_CASE(failed_create) | |||||||
| 				if (depth < 1024) | 				if (depth < 1024) | ||||||
| 					return this.stack(depth - 1); | 					return this.stack(depth - 1); | ||||||
| 				else | 				else | ||||||
| 					return f(0); | 					return address(f(0)); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	)"; | 	)"; | ||||||
| @ -12524,10 +12524,10 @@ BOOST_AUTO_TEST_CASE(staticcall_for_view_and_pure) | |||||||
| 				return (new C()).f(); | 				return (new C()).f(); | ||||||
| 			} | 			} | ||||||
| 			function fview() public returns (uint) { | 			function fview() public returns (uint) { | ||||||
| 				return (CView(new C())).f(); | 				return (CView(address(new C()))).f(); | ||||||
| 			} | 			} | ||||||
| 			function fpure() public returns (uint) { | 			function fpure() public returns (uint) { | ||||||
| 				return (CPure(new C())).f(); | 				return (CPure(address(new C()))).f(); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	)"; | 	)"; | ||||||
|  | |||||||
| @ -3,11 +3,11 @@ | |||||||
| contract B { | contract B { | ||||||
| 	A a; | 	A a; | ||||||
| 	constructor() public { | 	constructor() public { | ||||||
| 		a = new A(this); | 		a = new A(address(this)); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| contract A { | contract A { | ||||||
| 	constructor(address a) internal {} | 	constructor(address) internal {} | ||||||
| } | } | ||||||
| // ---- | // ---- | ||||||
| // TypeError: (141-146): Contract with internal constructor cannot be created directly. | // TypeError: (141-146): Contract with internal constructor cannot be created directly. | ||||||
|  | |||||||
| @ -3,9 +3,9 @@ contract A { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| contract B { | contract B { | ||||||
|     constructor(address) public { |     constructor(C) public { | ||||||
|     } |     } | ||||||
|     function b(address) public returns (A) { |     function b(C) public returns (A) { | ||||||
|         return new A(); |         return new A(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,6 @@ | |||||||
|  | contract C { | ||||||
|  |   function f() public pure returns (C c) { | ||||||
|  |     c = C(address(2)); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // ---- | ||||||
| @ -0,0 +1,7 @@ | |||||||
|  | contract C { | ||||||
|  |   function f() public view { | ||||||
|  |     C c = address(2); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // ---- | ||||||
|  | // TypeError: (46-62): Type address is not implicitly convertible to expected type contract C. | ||||||
| @ -0,0 +1,7 @@ | |||||||
|  | contract C { | ||||||
|  |   function f() public view { | ||||||
|  |     address a = address(this); | ||||||
|  |     a; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // ---- | ||||||
| @ -0,0 +1,8 @@ | |||||||
|  | contract C { | ||||||
|  |   function f() public view { | ||||||
|  |     address a = this; | ||||||
|  |     a; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // ---- | ||||||
|  | // TypeError: (46-62): Type contract C is not implicitly convertible to expected type address. | ||||||
							
								
								
									
										9
									
								
								test/libsolidity/syntaxTests/types/contract_to_base.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								test/libsolidity/syntaxTests/types/contract_to_base.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | contract A {} | ||||||
|  | contract B is A {} | ||||||
|  | contract C { | ||||||
|  |   function f() public { | ||||||
|  |     A a = new B(); | ||||||
|  |     a; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // ---- | ||||||
							
								
								
									
										10
									
								
								test/libsolidity/syntaxTests/types/contract_to_base_base.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								test/libsolidity/syntaxTests/types/contract_to_base_base.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | contract A {} | ||||||
|  | contract B is A {} | ||||||
|  | contract C is B {} | ||||||
|  | contract D { | ||||||
|  |   function f() public { | ||||||
|  |     A a = new C(); | ||||||
|  |     a; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // ---- | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | contract B {} | ||||||
|  | contract A is B {} | ||||||
|  | contract C { | ||||||
|  |   function f() public pure { | ||||||
|  |     A a = A(new B()); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // ---- | ||||||
|  | // TypeError: (85-95): Explicit type conversion not allowed from "contract B" to "contract A". | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | contract A {} | ||||||
|  | contract B {} | ||||||
|  | contract C { | ||||||
|  |   function f() public pure { | ||||||
|  |     B b = B(new A()); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // ---- | ||||||
|  | // TypeError: (80-90): Explicit type conversion not allowed from "contract A" to "contract B". | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user